GORM直接访问hasMany关系中的实例

时间:2016-04-01 03:10:46

标签: grails gorm grails-domain-class

我有两个域类CGroup和Directory,我想建模一个有许多目录的CGroup,但是这些目录中的一个被称为“根”,可以直接从CGroup访问。任何CGroup都应该只有一个root。并且级联应该仍然有效,删除任何目录都会删除它的所有子目录。

虽然错了,但这是我到目前为止所做的:

class CGroup{
    ...
    Directory root

    static hasMany = [directory:Directory]

    static constraints = {
        root(unique:true)
    }
}

class Directory {

    static hasMany = [children:Directory]
    ...
    static belongsTo = [parent:Directory,
                        cgroup:CGroup]

    static constraints = {
        parent nullable: true
    }
}

基本上,我只需要引用“many”集合中的一个实例,存储在“one”方面

1 个答案:

答案 0 :(得分:1)

我尝试了几种不同的方式,唯一能让它工作的方法是让root暂时可以为空。没有这个的问题是由于排序 - 因为Directory个实例在hasMany中,所以在保存CGroup或者save()调用失败之前无法保存它们。 cgroup为null(调用addToDirectory时设置)。但如果没有设置root属性,如果它不可为空,则无法保存CGroup。

所以我使root可以为空,但添加了一个自定义验证程序,如果root为空并且hasMany中有任何实例,则验证失败:

static constraints = {
   root nullable: true, validator: { Directory root, CGroup cgroup ->
      if (!root && cgroup.directory?.size()) {
         return ['root.required']
      }
   }
}

因此,您可以使用任何必需的值并且没有任何关联的CGroup实例来保存Directory实例。然后使用Directory附加addToDirectory个实例,并使用自定义设置器设置root实例:

void setRoot(Directory root) {
   if (this.root) {
      removeFromDirectory this.root
   }

   if (root) {
      addToDirectory root
   }

   this.root = root
}

再次保存:

def group = new CGroup(...).save()

group.root = new Directory(...)
group.addToDirectory(new Directory(...))
group.addToDirectory(new Directory(...))
group.save()

g1.errors