复合元素可以在Hibernate中包含集合

时间:2014-09-03 05:16:23

标签: java hibernate

根据hibernate documentation,它说:

  

组件的属性可以是任何Hibernate类型   (集合,多对一关联,其他组件等)。嵌套   组件不应被视为异国情调。 Hibernate是   旨在支持细粒度对象模型。

通过这个声明,我理解我可以声明一个具有可以是集合的属性的组件。

现在,医生又说:

  

复合元素可以包含组件但不包含集合。如果你的   复合元素包含组件,使用    标签。这个案例是一个集合   组件本身具有组件。你可能想考虑一下   如果一对多关联更合适。改造了   复合元素作为一个实体,但要注意即使是Java   模型是相同的,关系模型和持久性语义是   仍然略有不同。

所以这里说复合元素可以包含组件但不包含集合。与上述语句相矛盾,有人可以解释一个组件是否可以有一个集合。如果可能的话请提供一个小例子。

1 个答案:

答案 0 :(得分:2)

没有复合元素不能包含集合。但组件可以。让我试着用这种方式解释一下:

  • 第一个引用是关于<component>元素,而
  • 第二个是关于<composite-element>

它们都允许我们映射值类型对象(与参考类型相反) - 正如这里详细讨论的那样:

那么,区别在哪里?为什么第一个<component>可以包含集合,而第二个<composite-element>不能?简化的答案是:

  

因为<composite-element>已经是集合项的映射。

另一方面,<component>是根 - <class>级别的映射。

完整而且更好的答案是:

  

这两种类型的都有自己的ID,它们是关系数据库结构中的KEY。这就是为什么它们被视为价值类型 - 它们不能被引用。

     
      
  • <component> 与其根<class>一对一关系 - 它可以访问根/类ID。因此,它可以路径收集<key column="">根id。
  •   
  • <composite-element> 无法访问其ID / Key (根本不存在),与不在同一级别<component> 即可。没有地方可以像我们使用组件
  • 那样作弊   

所以,虽然我们可以看到这样的映射

<class name="eg.Person" table="person">
    <id ...
    ...
    <component name="Name" class="eg.Name" unique="true">
        <parent name="namedPerson"/> //reference back to the Person
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>

        // here we go 
        // collection mapped inside of the <component>

        <set name="celebrationDates" table="name_Dates">
           <key column="person"/>
          <element column="name" type="date"/>
        </set>
    </component>
</class>

使用<composite-element>,我们最终会得到一个集合项映射:

<class name="eg.Order" .... >
    ....
    <set name="purchasedItems" table="purchase_items" lazy="true">
        <key column="order_id">
        <composite-element class="eg.Purchase">
            <property name="purchaseDate"/>
            <property name="price"/>
            <property name="quantity"/>
            <many-to-one name="item" class="eg.Item"/>

            // this is already component
            // but without ID to be used 
            // as a reference on the other side of bidirectional relation

        </composite-element>
    </set>
</class>

总结,两个映射都试图提供类似的功能。它们有不同的名称,因为它们用于不同的场景。

我们可以想象,即使<composite-element>的集合也可以正常工作,如果我们 ...并停在此处。如果我们需要,请不要使用组件。使用完整的<class>映射。