Grails - 防止递归的一对多关系

时间:2011-10-27 13:11:43

标签: grails gorm

我在Grails中有以下域类:

class TreeNode {
    String name
    String description

    static hasMany = [childNodes: TreeNode]
}

确保TreeNode实例不能成为孩子的最常用的Grails方法是什么?我可以将此作为域类中的约束,还是应该在TreeNodeController的Save操作中编写自定义代码?

2 个答案:

答案 0 :(得分:1)

将其作为自定义约束。

static constraints = {
  childNodes(validator: {value, obj, errors->
      if(value.contains(obj) {
        errors.rejectValue('childNodes', 'Cannot contain self')
      }
  }
}

答案 1 :(得分:1)

答案取决于您想要在孩子中检查的深度。如果你只是担心直接的孩子,那么来自@Tiggerizzy的代码应该可以正常工作。

另一方面,如果要验证节点不是树中的直接或深层子节点,则应退出逻辑并将其置于Grails服务类中。这将提供至少两个好处:

  1. 如果节点中的其他属性发生更改,而不是树的结构,则可以跳过子检查验证,并在验证时节省额外的处理时间。
  2. 如果您是从树的近处或根处进行验证,那么验证所有子子对于大型树来说将是一个较长的过程,涉及大量数据库工作。通过在Service类中执行此工作,您将获得Service的事务性质,这将在未处理的Exception上回滚任何数据库更改,例如在与另一个线程的乐观锁定情况下。