我必须在每个方向分配关系吗?使用textbook domain classes for the hasOne relationship,到目前为止,我的测试似乎有必要让实例相互识别:
def face = new Face()
def nose = new Nose()
face.nose = nose
nose.face = face
但是,我不知道为什么。这是非常尴尬的。我期待有更好的方法。
编辑:
我需要关系分配的帮助。我不需要有关在域类中建立hasOne关系的机制的信息,或者关于双向引用的智慧的讨论。我想知道为什么只需要单个语句来设置nose实例和face实例之间的关系。
我的双语句解决方案基于我在复杂应用程序中遇到的麻烦。我将尝试在一个简单的例子中重现我的经验。
答案 0 :(得分:17)
直接回答
建立关系的需要,即分配鼻子到脸部和面对节点,并不是很尴尬。 Hibernate是一个 RELATIONSHIP 映射器,因此您需要使关系显式化。也就是说,您可以通过定义
来编写更少的代码setNose(nose){
this.nose = nose
nose.face = this
}
在脸上现在当你执行face.nose = nose
时,会为你调用setter,并按照你想要的方式设置关系。
一般有用的想法
通常,您无需在两个方向上分配关系。拥有单向或双向关系是完全有效的。
但是,hasOne
定义具有非常具体的含义。文档非常清楚地说明了hasOne的目的是告诉hibernate将定义关系的键放在子节点中,在本例中为Nose。如果你仔细考虑它,你会发现的关系应该是双向的。以下是思路:
1)你在脸上定义了hasOne(即父母)
2)即使您在父项上定义了hasOne,受影响的基础表也是子表(即Nose上的face_id列)
3)由于外键在孩子身上,孩子必须引用其父母。如果没有,您将在子项上拥有属于外键但与对象无关的属性
4)请记住,您正在使用ORM的机器来定义关系。虽然您可以手动将face_id字段添加到Nose,并在代码中设置值(即自己管理关系而不让ORM工具执行此操作),但是您明确使用ORM这一事实意味着ORM工具将管理关系对你而言。
class FaceTests extends GroovyTestCase {
public void testStuff(){
Face face = new Face()
Nose nose = new Nose()
face.nose = nose;
face.save(flush:true)
assertNotNull face.id
assertNotNull nose.id
}
}
,结果是一个包含
的异常hasOne property [Face.nose] is not bidirectional. Specify the other side of the relationship!
因此,框架甚至可以确保,当您使用hasOne时,您将拥有双向关系。