我想在 Grails GORM 中创建一个树状结构。该结构应该是其他对象的容器,并且应该完全满足以下要求:
- 一个节点应该有 0 到 n 个子节点
- 一个节点应该只有一个父节点
- 一个节点应该有 0 到 n 个兄弟节点
如何在 Grails GORM 中定义这样的结构?
我尝试了以下课程:
Class TreeNode {
String name
TreeNode parent
static hasMany = [children: TreeNode]
//returns the root node, and by extension, the entire tree!
TreeNode getRootNode(){
if(parent){
//if parent is not null then by definition this node is a child node of the tree.
return parent.getRootNode()
}else{
//if parent is null then by definition it is the root node.
return this
}
}
//you might not need this function, but ill add it as it is common in tree structures
boolean isLeaf(){
//determines if this node is a leaf node. a leaf is a node with zero childrens
return children.isEmpty()
}
}
但是在启动时我收到以下错误:
ERROR context.ContextLoader - Context initialization failed
Message: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Property [children] in class [class test.TreeNode] is a bidirectional one-to-many with two possible properties on the inverse side. Either name one of the properties on other side of the relationship [treeNode] or use the 'mappedBy' static to define the property that the relationship is mapped with. Example: static mappedBy = [children:'myprop']
Line | Method
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by GrailsDomainException: Property [children] in class [class test.TreeNode] is a bidirectional one-to-many with two possible properties on the inverse side. Either name one of the properties on other side of the relationship [treeNode] or use the 'mappedBy' static to define the property that the relationship is mapped with. Example: static mappedBy = [children:'myprop']
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
| Error 2013-10-04 17:36:00,730 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Property [children] in class [class test.TreeNode] is a bidirectional one-to-many with two possible properties on the inverse side. Either name one of the properties on other side of the relationship [treeNode] or use the 'mappedBy' static to define the property that the relationship is mapped with. Example: static mappedBy = [children:'myprop']
Message: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Property [children] in class [class test.TreeNode] is a bidirectional one-to-many with two possible properties on the inverse side. Either name one of the properties on other side of the relationship [treeNode] or use the 'mappedBy' static to define the property that the relationship is mapped with. Example: static mappedBy = [children:'myprop']
Line | Method
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by GrailsDomainException: Property [children] in class [class test.TreeNode] is a bidirectional one-to-many with two possible properties on the inverse side. Either name one of the properties on other side of the relationship [treeNode] or use the 'mappedBy' static to define the property that the relationship is mapped with. Example: static mappedBy = [children:'myprop']
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread