【问题标题】:Hibernate: org.hibernate.WrongClassException, SINGLE_TABLE inheritance and DiscriminatorFormulaHibernate:org.hibernate.WrongClassException、SINGLE_TABLE 继承和 DiscriminatorFormula
【发布时间】:2011-08-05 18:38:50
【问题描述】:

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

【问题讨论】:

  • 我经历过这个。如果可以,请将调试器附加到 Hibernate LoaderSingleTableEntityPersister 类。后者将实际的子类存储在字段subclassesByDiscriminatorValue 中。检查密钥,并比较那里实际传递的内容。您的输入看起来可疑地用空格填充。

标签: java hibernate hsqldb single-table-inheritance


【解决方案1】:

确保实体列在您的配置文件中(例如,persistence.xml)。来自https://stackoverflow.com/a/14150629/116596

【讨论】:

    【解决方案2】:

    问题是你得到了一个 A 的列表,而 Hibernate 没有足够的知识来根据判​​别器公式在列表中创建 B 或 C。幸运的是,有一个注释可以解决这个问题。

    有些人称这是一个错误,我有点同意。无论如何,抽象似乎有点漏洞。

    给父实体(A)添加@ForceDiscriminator注解,它可能会正常工作。

    此解决方案是特定于 Hibernate 的。我不确定这个问题是否普遍延伸到 JPA,或者是否有 JPA 解决方案。

    编辑:

    这似乎没有成功。

    尝试获取 hibernate 为您生成的 sql 可能是值得的。

    添加

    <property name="hibernate.show.sql" value="true" />
    

    到你的休眠配置,看看会发生什么。

    获取这个带有和不带有 force 子句的 sql 可能会提供关于 force 的确切作用以及它为什么不起作用的线索。

    目前我想不出其他任何东西,除了您的鉴别器公式中的 NULL 看起来有点冒险。

    【讨论】:

    • 它没有用。在将 @ForceDiscriminator 添加到 A 后,我仍然会收到 WrongClassException。还有其他想法吗?谢谢!
    【解决方案3】:

    嗯,这让我很好奇:可能是你遭受了this issue 的痛苦,它说:

    原因是字符串被解释为 CHAR 类型而不是 VARCHAR。我们将来可能会改变这种行为。

    您能否尝试对结果应用 TRIM()(在 @DiscriminatorFormula 内)或使用另一个 DBMS 进行测试?这似乎不是 Hibernate 特有的。

    【讨论】:

      【解决方案4】:

      我使用 DTYPE 列和 WHERE 子句解决了这个问题。 以您的示例为例,它将是:

      @Entity
      @WHERE(clause = "DTYPE = 'B'")
      public class B extends A {
       ...
      }
      
      
      @Entity
      @WHERE(clause = "DTYPE = 'C'")
      public class C extends A {
       ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        相关资源
        最近更新 更多