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

Grails-防止递归的一对多关系,grails,gorm,Grails,Gorm,我在Grails中有以下域类: class TreeNode { String name String description static hasMany = [childNodes: TreeNode] } Grails最惯用的方法是什么来确保TreeNode实例不能将自己作为子实例?我可以在域类中作为约束执行此操作,还是应该在TreeNodeController上的保存操作中编写自定义代码?作为自定义约束执行此操作 static constraints = {

我在Grails中有以下域类:

class TreeNode {
    String name
    String description

    static hasMany = [childNodes: TreeNode]
}

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

作为自定义约束执行此操作

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

答案取决于你想在孩子们内部检查的深度。如果您只担心直系子女,那么@Tiggerizzy的代码应该可以正常工作

另一方面,如果您想验证节点不是树中的直接子节点或深层子节点,那么应该将该逻辑从验证中拉出来并放在Grails服务类中。这至少有两个好处:

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