为什么Hibernate有时会加载不正确的子类的实例?

Tim*_*ima 9 java oracle hibernate

我们有一个奇怪的问题,我们无法解释hibernate.

我们有什么:

  1. 一个抽象类和它的两个子类.我们称它们为A,SubA1,SubA2
  2. 我们有另一个抽象类和一些子类.让我们调用B,SubB1,SubB2.
  3. SubB1和A之间存在多对一关系.
  4. 类A和B的hibernate映射如下所示:

    <hibernate-mapping>
    
      <class name="A" table="A" lazy="false">
    
        <id name="id" column="ID" type="java.lang.Integer">
          <generator class="org.hibernate.id.enhanced.TableGenerator">
            <param name="segment_value">a</param>
          </generator>
        </id>
    
        <version name="olVersion" column="VERSION" type="integer" unsaved-value="negative" />
    
        <joined-subclass name="SubA1" table="SUB_A1" lazy="false">
          <key column="ID_A" foreign-key="FK_SUB_A1_A"/>
          <property name="p1" column="p1" length="255" unique="true"/>
          <property name="p2" column="p2" length="255" not-null="true" />
        </joined-subclass>
    
        <joined-subclass name="SubA2" table="SUB_A2" lazy="false">
          <key column="ID_A" foreign-key="FK_SUB_A2_A"/>
          <property name="p3" column="p3" length="255" not-null="true" unique="true" />
          <property name="p4" column="p4" length="4000" />
        </joined-subclass>
    
      </class>
    
    </hibernate-mapping>
    
    Run Code Online (Sandbox Code Playgroud)

<hibernate-mapping>

  <class name="B" table="B" lazy="false">

    <cache usage="read-write"/>

    <id name="id" column="ID" type="java.lang.Integer">
      <generator class="org.hibernate.id.enhanced.TableGenerator">
        <param name="segment_value">b</param>
      </generator>
    </id>

    <version name="olVersion" column="VERSION" type="integer" unsaved-value="negative" />

    <joined-subclass name="SubB1" table="SUB_B1" lazy="false">
      <key column="ID_B" foreign-key="FK_SUB_B1_B"/>
      <many-to-one name="subA" column="ID_A" not-null="false" update="false" foreign-key="FK_SUB_B1" lazy="false" class="A"/>
    </joined-subclass>

  </class>

</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)

现在的问题是:有时候hibernate通过加载SubB1的项目将SubA2的项目作为SubA1的实例加载,但并非所有项目都会输错,只有少数项目和每次都不是相同的项目.

也许有人可以解释,出现什么问题或者我们的hibernate映射有什么问题.

先感谢您.

PS.出现此问题:

  • JDK 1.7.71
  • Oracle 12g
  • Hibernate 3.6.10

我没有尝试其他配置.

不幸的是,我没有示例应用程序,但我也无法提供真实应用程序的源代码.

mal*_*una 1

我认为你的休眠映射是正确的。因此,如果您有错误,我确信它会在施法时发生。我多次遇到这个问题,我总是使用访问者模式来解决它。

访问者模式的另一个优点是您不需要强制lazy=false,因为它完美地解决了代理对象的真实类型。

如何解决您的问题

我建议您创建一个类,为每个具体Visitor子类实现两个方法:visit

  • void visit(SubA1 object)
  • void visit(SubA2 object)

这两个方法的实现都是当A实例是SubA1SubA2具体类时要执行的代码。我设置了 void return,但显然你可以更改它。

另一方面,A类必须添加抽象访问方法public abstract void visit(Visitor visitor);。我再次输入了voidreturn,但是您必须使其适应visit方法的返回类型。

SubA1SubA2必须按如下方式实现此方法:

public void accept(Visitor visitor) {
    visitor.visit(this);
}
Run Code Online (Sandbox Code Playgroud)

这样,当您运行此代码时,objectA.accept(visitor)Java 必须在运行时解析真实类型,而objectA无需强制转换,并且不会出现错误。它确实有效,我在 Hibernate 3.x 和 4.x 中使用它已经很多年了。

访客模式文档

这里有一篇非常好的文章代理访问者模式,您可以在其中找到如何在使用代理和非代理对象时将访问者模式应用于休眠。

希望能帮助到你!