映射父子关系 - 由两个对象的字段组成的复合键

时间:2010-08-26 19:56:12

标签: hibernate orm jpa

有三个对象实体:GrandParent,Parent和Child

  • GrandParent包含grandParentId
  • Parent包含对象GrandParent,parentId,一些属性和Child列表。
  • Child包含childId和一些属性。

有四个表:GrandParent,Parent,Child,ParentsChildrenList

  • 主键为{grandParentId}
  • 的GrandParent
  • 主键为{grandParentId,parentId}
  • 的父级
  • 主键为{grandParentId,childId}
  • 的子项
  • ParentsChildrenList,其主键为{grandParentId,parentId,childId}

父和子都由复合键标识。

如何映射这种关系?请注意,对象Child不包含对Parent或GrandParant的引用,但表Child使用grandParentId作为其主键的一部分。

该表结构满足用例。但是,映射并不是直截了当的。任何设计见解都表示赞赏。

[--- Update 1 ---]

我将对象GrandParent添加到Child,并创建了用于映射到表的复合键ChildId 问题仍然存在:儿童可以从父母那里借一部分身份证吗?这样我就不需要在Child中引入GrandParent纯粹是为了坚持。

[--- Update 2 ---]

我从Child中删除了对象GrandParent,但保留了ChildId和允许设置grandParentId的方法。事情仍然按预期工作。我怀疑这不能进一步减少。

2 个答案:

答案 0 :(得分:2)

我最直接的见解就是做hibernate推荐的,使用代理键。这意味着每个类只有一个id用于持久性目的。您仍然可以映射自然键。否则你真的在与框架作斗争,你不会感到高兴。

也就是说,我所在的团队通过为id创建自定义类型解决了这个问题,其中一个部分已分配并且已生成。

这也可能有所帮助 http://opensource.atlassian.com/projects/hibernate/browse/HHH-2060

答案 1 :(得分:0)

要添加其他帖子提到的内容,创建自定义类型可以在定义键时提供更大的灵活性。您还可以使用具有单个列的自定义ID类型,但添加您自己的自定义逻辑以根据构造函数的参数生成代理键。

复合示例:

      (Child ) 
      public class Child implements java.io.Serializable {
         private ChildId id;
             ....
      (ChildId )
      public class ChildId implements java.io.Serializable {
        private long id;
        private long parent_id;
            .....
     (Child.cfg.xml)
          ....
      <composite-id name="id" class="ChildId">
        <key-property name="id" type="long">
            <column name="id" />
        </key-property>
        <key-property name="parent_id" type="long">
            <column name="parent_id" />
        </key-property>
      </composite-id>
         .....

用法:

   Child c = new Child ();
   ChildId cid = new ChildId(null,1);
   c.setId(cid);
   session.save(c);

创建自定义类型允许与ORM紧密结合的大量自定义与在应用程序层中构建解决方案。