java Hibernate: org.hibernate.WrongClassException, SINGLE_TABLE 继承和 DiscriminatorFormula
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5667671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate: org.hibernate.WrongClassException, SINGLE_TABLE inheritance and DiscriminatorFormula
提问by Porcho
I'm using Hibernate 3.2.2 GA with HSQLDB 2.0 GA, and I have a class hierarchy similar to the following:
我将 Hibernate 3.2.2 GA 与 HSQLDB 2.0 GA 一起使用,并且我有一个类似于以下的类层次结构:
@Entity
@Table(name = "A_TABLE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(value = "case when CODE IN (1, 2, 3, 4) then 'TypeB'
when CODE IN (5, 6, 7, 8) then 'TypeC' else NULL end")
@org.hibernate.annotations.Entity(dynamicUpdate = true, dynamicInsert = true)
public abstract class A{
(...)
}
@Entity
@DiscriminatorValue("TypeB")
public class B extends A {
(...)
}
@Entity
@DiscriminatorValue("TypeC")
public class C extends A {
(...)
}
I'm trying to execute the following HQL query, which returns objects from both B and C classes.
我正在尝试执行以下 HQL 查询,它从 B 和 C 类返回对象。
String hql = "from A a where a.someAttr = 3";
Query query = session.createQuery(hql);
return query.list();
However, I get the following error:
但是,我收到以下错误:
org.hibernate.WrongClassException: Object with id: 2 was not of the specified subclass: A (Discriminator: C )
The strangest thing is that the object with id 2 isa C instance...
最奇怪的是,id 为 2 的对象是一个 C 实例......
I've googled for this error and I've found some people who's faced it, none using InheritanceType.SINGLE_TABLE
and DiscrimatorFormula
, though. Has anyone run into this problem?
我在谷歌上搜索了这个错误,我发现一些人遇到了这个错误,但没有使用InheritanceType.SINGLE_TABLE
and DiscrimatorFormula
。有没有人遇到过这个问题?
回答by Idris Mokhtarzada
Make sure the entity is listed in your config file (persistence.xml, for example). From https://stackoverflow.com/a/14150629/116596
确保实体在您的配置文件(例如,persistence.xml)中列出。来自https://stackoverflow.com/a/14150629/116596
回答by javaboygo
I solved it using the DTYPE column and WHERE clause. With your example, it would be:
我使用 DTYPE 列和 WHERE 子句解决了它。以您的示例,它将是:
@Entity
@WHERE(clause = "DTYPE = 'B'")
public class B extends A {
...
}
@Entity
@WHERE(clause = "DTYPE = 'C'")
public class C extends A {
...
}
回答by Don Roby
The problem is that you're getting a list of A's and Hibernate doesn't know enough to create B's or C's in a list based on the discriminator formula. Luckily, there's an annotation to deal with this.
问题是你得到了一个 A 的列表,而 Hibernate 没有足够的知识来根据鉴别器公式在列表中创建 B 或 C。幸运的是,有一个注释可以解决这个问题。
Some people call this a bug, and I'm sort of inclined to agree. At any rate, the abstraction seems to be a bit leaky.
有些人称这是一个错误,我有点同意。无论如何,抽象似乎有点漏洞。
Add a @ForceDiscriminator
annotation to the parent entity (A
) and it's likely to work properly.
@ForceDiscriminator
向父实体 ( A
)添加注释,它可能会正常工作。
This solution is Hibernate-specific. I'm not sure if the problem extends to JPA in general or if there's a JPA solution.
此解决方案是特定于 Hibernate 的。我不确定问题是否一般扩展到 JPA 或者是否有 JPA 解决方案。
EDIT:
编辑:
This appears not to have done the trick.
这似乎没有成功。
It might be worthwhile to try to get the sql that hibernate is generating for you.
尝试获取 hibernate 为您生成的 sql 可能是值得的。
Add
添加
<property name="hibernate.show.sql" value="true" />
to your hibernate config and see what happens.
到您的休眠配置,看看会发生什么。
Getting this sql with and without the force clause might give clues as to exactly what the force does and why it's not working.
使用和不使用 force 子句获取此 sql 可能会提供有关 force 的确切作用以及它为什么不起作用的线索。
I can't think of anything else at the moment, except the NULL
in your discriminator formula looks a little risky.
我目前想不出其他任何东西,除了NULL
你的鉴别器公式中的看起来有点冒险。
回答by mabi
Well, this got me curious: it may be you suffer from this issuewhich says:
好吧,这让我很好奇:可能是您遇到了这个问题,它说:
The reason is the string is interpreted as a CHAR type rather than VARCHAR. We may change this behaviour in the future.
原因是字符串被解释为 CHAR 类型而不是 VARCHAR。我们将来可能会改变这种行为。
Can you try to apply TRIM() on the result (inside the @DiscriminatorFormula
) or test with another DBMS? This doesn't seem to be Hibernate specific.
您可以尝试对结果(在 内@DiscriminatorFormula
)应用 TRIM( ) 或使用另一个 DBMS 进行测试吗?这似乎不是 Hibernate 特有的。