具有自联接的层次结构的Hibernate映射

时间:2016-12-02 20:55:49

标签: java hibernate

我有一个有趣的场景,我试图确定类的层次结构(需要是XML映射文件)的Hibernate映射以及所需的表。 我有一个类Base,它由A,B和C类扩展。

    Class Base
     |   |    |       
Class A  |  Class B
       Class C

Class Base {
   String  type;
   Double  average;
}
Class A extends Base {       
   Map<String, Integer>   aValues;
}
Class B extends Base {
   Map<String, Double>    bValues;
}

Q.1)没有任何额外的属性&#39;在类A和B中,使用Hibernate,映射将转到子表。那么我可以将子类A和B映射到与类Base相同的表(假设A和B的hibernate映射包括它们持有的特定集合,如下所示)?我的意思是这样的自我加入/工会是合法的吗?:

<hibernate-mapping package="mypackage">
  <class name="Base" table="BASE">  
    <id name="id" column="ID">
        <generator class="assigned"/>
    </id>       
    <property name="type" />
    <property name="average" column="AVERAGE" />

    <union-subclass name="A" table="BASE">
      <map name="aValues" table="A_VALUES" cascade="all" > 
       <key column="BASE_ID" not-null="true"/>
       <map-key column="name" type="string"/>
       <element column="value" type="int"/>
      </map>        
    </union-subclass>

   <union-subclass name="B" table="BASE">
      <map name="bValues" table="B_VALUES" cascade="all" > 
        <key column="BASE_ID" not-null="true"/>
        <map-key column="name" type="string"/>
        <element column="value" type="double"/>
      </map>        
   </union-subclass> 
  </class>
</hibernate-mapping>

我为A,B,C选择union-subclass而不是join-subclass的原因是为了避免必须将引用列返回到基类行。

Q.2)C类是一个包含A和B对象的复合物。

Class C extends Base {
  A  aObj;
  B  bObj:
}

如果对上面的Question1的答案是肯定的,那么C类也可以映射到Base,并且包含的​​对象将转到连接表吗?无论如何,应该使用什么策略将C与A和B的组合对象相关联? (我必须使用如下所示的丑陋加入吗?)

<hibernate-mapping>

  <union-subclass name="C" table="Base">    

    <join table="ASSOC" optional="true">
      <key column="parent_Id" unique="true"/>
      <many-to-one name="aObj" column="child_Id" not-null="true" unique="true"/>
    </join>     

    <join table="ASSOC" optional="true">
      <key column="parent_Id" unique="true"/>
      <many-to-one name="bObj" column="child_Id" not-null="true" unique="true"/>
    </join>     

  </union-subclass> 
</hibernate-mapping>

理想情况下,我想使用这样结构化的BASE表(映射类A,B,C和Base),而不是引入任何新的(join)表:

Table Base
Id | Type | Average | Parent_Id
 1   Base     null      null
 2    A       10.0       4
 3    B       20.0       4
 4    C       15.0      null

会欣赏任何想法/指针。

1 个答案:

答案 0 :(得分:0)

  

我为A,B,C选择union-subclass而不是join-subclass的原因是为了避免必须将引用列返回到基类行。

Q1

如果您认为A行,B行和C行可能具有相同的基类行,就像在关系中可能的那样,您的想法是错误的。数据库中的继承只适用于结构:A-table包含具有Base-class-table的所有列,但它没有任何行!这意味着:即使A,B和C有行,Base-class-table也可能为空!继承只影响结构,而不影响数据。

Q2

你的C类设计并不像“A和B的所有数据”那样复合。它就像“所有对A和B中现有行的引用”。

  

C类也可以映射到Base,包含的对象会连接到表吗?

未加入,引用,但是。

  

无论如何,应该使用什么策略将C与A和B的组合对象相关联?

不,继承结构或拥有user='Marcel'的策略对于hibernate中的bean很重要。对于使用继承方式,您可以编写如下内容:

forign key

给你两个不同的行。使用cardinailty你必须:

BaseClass patient1 = entityManager.find(A.class, 22);
BaseClass patient2 = entityManager.find(B.class, 22);
  

理想情况下,我想使用这样结构化的BASE表(映射类A,B,C和Base)

您描述的结构不可能使用继承,我也无法理解C patient = entityManager.find(C.class, 22); A a = patient.getA(); B b = patient.getB(); 的含义。但要实现此结构,您可以将只读Average映射到具有您无法更新的限制的实体,并删除该视图的实体。