有三个对象实体:GrandParent,Parent和Child
有四个表:GrandParent,Parent,Child,ParentsChildrenList
父和子都由复合键标识。
如何映射这种关系?请注意,对象Child不包含对Parent或GrandParant的引用,但表Child使用grandParentId作为其主键的一部分。
该表结构满足用例。但是,映射并不是直截了当的。任何设计见解都表示赞赏。
[--- Update 1 ---]
我将对象GrandParent添加到Child,并创建了用于映射到表的复合键ChildId 问题仍然存在:儿童可以从父母那里借一部分身份证吗?这样我就不需要在Child中引入GrandParent纯粹是为了坚持。
[--- Update 2 ---]
我从Child中删除了对象GrandParent,但保留了ChildId和允许设置grandParentId的方法。事情仍然按预期工作。我怀疑这不能进一步减少。
答案 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紧密结合的大量自定义与在应用程序层中构建解决方案。