我在 Grails 中有一个类似的树结构:
class TreeNode {
String name
// more properties
List children = []
static hasMany = [children: TreeNode]
static belongsTo = [parent: TreeNode, root: TreeNode]
static mappedBy = [children:'parent']
static constraints = {
name(blank: false,maxsize: 100,)
parent(nullable:true)
root(nullable:false)
}
}
出于 SQL 性能原因,我需要每条记录都直接引用其根节点。因此,“根”属性。
在我添加“root”之前,节点已正确保存。也就是说,我可以在根节点上调用 save() ,并且在所有节点中都正确分配了 parent_id 字段(根节点本身除外,其父 ID 保持为空)。
我试图在 beforeInsert() 中分配“根”,方法是向上走树直到找到父级。
def beforeInsert = {
def node = this
while (node.parent) {
node = node.parent
}
root = node
}
我经常遇到堆栈溢出异常。
at org.codehaus.groovy.grails.orm.hibernate.validation.HibernateDomainClassValidator.cascadeValidationToOne(HibernateDomainClassValidator.java:116)
at org.codehaus.groovy.grails.validation.GrailsDomainClassValidator.cascadeToAssociativeProperty(GrailsDomainClassValidator.java:142)
当堆栈溢出异常没有发生时,每个“根”引用自己而不是最终根。beforeInsert() 没有爬树。
你能帮我解决这个问题吗?GORM 会尝试以深度优先方式保存我的树结构吗?如果是这样,如果父级尚未持久化,它如何保存父级 ID?最重要的是,如何通过在根节点上调用 save() 来保存树,这样的“根”设置正确,而无需在 save() 之后(立即)更新所有节点?