如何在两个类之间设置适当的关系

时间:2015-03-23 21:45:33

标签: grails gorm

我在设置两个类之间的关系时遇到了一些问题。我有两节课,学生:

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)。所以我应该能够通过

获得孩子的名单
  1. father.children
  2. mother.children
  3. local_guard.children
  4. 如何在这些类之间设置正确的关系来解决我的问题?

2 个答案:

答案 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)

您可能希望使用hasManybelongsTo,然后定义监护人,您可能希望在监护人对象中使用父亲,母亲,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号相关的错误,因此您需要确保在创建和修改这些关系时确保关系的两侧都已定义对象。