我在设置两个类之间的关系时遇到了一些问题。我有两节课,学生:
class Student {
String name
Guardian father
Guardian mother
Guardian local_guardian
}
和卫报:
class Guardian {
String name;
static hasMany = [children:Student]
static mappedBy = [children:'father']
}
在这里,我使用mappedBy将Guardian对象映射到父属性。除非mappedBy,我得到错误告诉,应该使用mappedBy与3个Student类属性中的任何一个。 我尝试了这个查询来输入一些示例数据
new Student(name:"John", father: new Guardian(name:"Michael").save(),
mother: new Guardian(name:"Mary").save(),
local_guardian: new Guardian(name:"James").save()).save(flush:true);
数据已成功保存,但我的问题是,因为我使用了mappedBy和'father'属性,所以我只能将Guardian.children与该父对象一起使用。 当我试图获得有母亲和local_guardian对象的孩子名单时, (例如:mother.children)获得null结果。 我尝试在很多方面添加addTo,如
Guardian.findByName("Mary").addToChildren(
Student.findByName("John")).save(flush:true);
并尝试访问
Guardian.findByName("Mary").children
在这里,我得到了结果,但它将孩子从父亲移动到母亲对象,并且无法再访问father.children
我该如何解决这个问题呢?
我想要实现的是,我应该能够从所有3个Guardian对象中获取子列表。这里有一个Student对象指向3个Guardian对象(父亲,母亲,local_guardian)。所以我应该能够通过
如何在这些类之间设置正确的关系来解决我的问题?
答案 0 :(得分:1)
如果你想使用hasMany实现这种关系,那么你需要在Guardian类中有三个mappedBy。
static hasMany = [children:Student, motherChildres:Student, localGuardianChildrens:Student]
static mappedBy = [children:'father', motherChildrens:'mother', localGuardianChildrens: 'local_guardian']
但这看起来不太好,相反,您可以使用中级域类实现关系,并在Guardian类中添加addToChildren和getChildrens方法,如下所示。
class GuardianChildren {
Guardian guardian
Student student
constraints {
student unique: ['guardian']
}
}
Guardian {
void addToChildrens(Student child) {
new GuardianChildren(guardian:this, student:child).save()
}
@Transient
List<Student> getChildrens() {
return GuardianChildren.findAllByGuardian(this).children
}
}
Student {
@Transient
Guardian getMother() {
//find guardin children where guardian type is mother and children is this student
}
@Transient
Guardian getFather() {..}
}
从学生中删除来自Guardian和父/母属性的hasMany。您可能还需要Guardian中的类型字段来指定这是否是母亲/父亲等
答案 1 :(得分:0)
您可能希望使用hasMany
和belongsTo
,然后定义监护人,您可能希望在监护人对象中使用父亲,母亲,localGuardian属性。通过这种关系,您可以使用transients
来定义子集和母亲/父亲。
所以例如
class Student
{
String name
Guardian local_guardian
static belongsTo = [primaryGuardian: Guardian]
static transients=['mother', 'father']
//define the transients
def getMother(){
if(primaryGuardian.type == 'mother') {
return primaryGuardian
} else {
return primaryGuardian.spouse
}
}
//do something similiar for getFather
}
Class Guardian
{
String name
String type
Guardian spouse
static hasMany = [children:Student, localGuardianStudents: Student]
}
请注意,这只是示例代码,可能包含错误,因为我没有对其进行测试 因此,您可以创建一个监护人,然后通过调用
添加子项guardian.addToChildren(child)
无论如何,这将让你通过致电guardian.children
来获得监护人的孩子,它可以让你通过拨打child.primaryGuardian
来获得孩子的主要监护人(母亲或父亲),并且让你通过调用child.mother
来获得母亲或父亲,而无需在那里添加特殊类型。
您需要确保在此修改约束,以便配偶可以为null。此外,当您尝试保存时,这种性质的关系有时会变得棘手,从而导致与丢失ID号相关的错误,因此您需要确保在创建和修改这些关系时确保关系的两侧都已定义对象。