我正在使用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 {
(...)
}
我正在尝试执行以下HQL查询,该查询返回B和C类中的对象。
String hql = "from A a where a.someAttr = 3";
Query query = session.createQuery(hql);
return query.list();
但是,我收到以下错误:
org.hibernate.WrongClassException: Object with id: 2 was not of the specified subclass: A (Discriminator: C )
最奇怪的是id为的对象是一个C实例......
我已经搜索了这个错误,但我找到了一些人,但没有人使用InheritanceType.SINGLE_TABLE
和DiscrimatorFormula
。有人遇到过这个问题吗?
答案 0 :(得分:5)
确保实体列在配置文件中(例如,persistence.xml)。来自https://stackoverflow.com/a/14150629/116596
答案 1 :(得分:1)
问题在于你得到的A列表和Hibernate不足以根据鉴别器公式在列表中创建B或C.幸运的是,有一个注释可以解决这个问题。
有些人称这是一个错误,我有点倾向于同意。无论如何,抽象似乎有点漏洞。
向父实体(@ForceDiscriminator
)添加A
注释,它可能正常工作。
此解决方案特定于Hibernate。我不确定问题是否一般延伸到JPA,或者是否有JPA解决方案。
修改强>
这似乎没有成功。
尝试获取hibernate为您生成的sql可能是值得的。
添加
<property name="hibernate.show.sql" value="true" />
到你的hibernate配置,看看会发生什么。
使用和不使用force子句获取此sql可能会提供关于力量究竟是什么以及为什么它不起作用的线索。
我现在想不出任何其他事情,除了你的鉴别器公式中的NULL
看起来有点风险。
答案 2 :(得分:1)
嗯,这让我很好奇:你可能会因为this issue而感到痛苦:
原因是字符串被解释为CHAR类型而不是 VARCHAR。我们将来可能会改变这种行为。
您可以尝试对结果应用TRIM()(在@DiscriminatorFormula
内)或使用其他DBMS进行测试吗?这似乎不是特定于Hibernate的。
答案 3 :(得分:1)
我使用DTYPE列和WHERE子句解决了它。 举个例子,它将是:
@Entity
@WHERE(clause = "DTYPE = 'B'")
public class B extends A {
...
}
@Entity
@WHERE(clause = "DTYPE = 'C'")
public class C extends A {
...
}