Hibernate:org.hibernate.WrongClassException,SINGLE_TABLE继承和DiscriminatorFormula

时间:2011-04-14 18:15:31

标签: java hibernate hsqldb single-table-inheritance

我正在使用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_TABLEDiscrimatorFormula。有人遇到过这个问题吗?

4 个答案:

答案 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 {
 ...
}