问题描述
|
我将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为2的对象是一个C实例...
我已经搜寻了这个错误,但发现有人遇到了这个错误,但是没有人使用InheritanceType.SINGLE_TABLE
和discrimatorFormula
。有没有人遇到这个问题?
解决方法
确保在配置文件中列出了该实体(例如,persistence.xml)。从https://stackoverflow.com/a/14150629/116596
,问题在于您正在获得A \的列表,而Hibernate却不足以根据鉴别器公式在列表中创建B \或C \。幸运的是,有一个注释可以解决这个问题。
有人称它为错误,我有点同意。无论如何,抽象似乎有点漏水。
向父实体(
A
)添加一个@ForceDiscriminator
批注,它可能会正常工作。
该解决方案是特定于Hibernate的。我不确定该问题是否普遍存在于JPA或是否有JPA解决方案。
编辑:
这似乎还没有解决问题。
尝试获取hibernate为您生成的sql可能是值得的。
加
<property name=\"hibernate.show.sql\" value=\"true\" />
到您的休眠配置,看看会发生什么。
使用force子句和不使用force子句获取此sql可能会提供线索,以确切说明force的作用以及为何不起作用。
目前我什么也没想,除了判别式中的ѭ8看起来有点冒险。
,好吧,这让我感到好奇:这可能是您受此问题困扰:
原因是字符串被解释为CHAR类型而不是
VARCHAR。我们将来可能会改变这种行为。
您可以尝试对结果(在ѭ9result内)应用TRIM()还是用另一个DBMS进行测试?这似乎不是特定于Hibernate的。
,我使用DTYPE列和WHERE子句解决了它。
以您的示例为例:
@Entity
@WHERE(clause = \"DTYPE = \'B\'\")
public class B extends A {
...
}
@Entity
@WHERE(clause = \"DTYPE = \'C\'\")
public class C extends A {
...
}