Spring Grails-GORM中的树状结构

Spring Grails-GORM中的树状结构,spring,hibernate,grails,gorm,grails-2.0,Spring,Hibernate,Grails,Gorm,Grails 2.0,我想在Grails GORM中创建一个树状结构。该结构应为其他物体的容器,并应完全满足以下要求: 一个节点应该有0到n个子节点 一个节点应该只有一个父节点 节点应具有0到n个同级节点 如何在Grails GORM中定义这样的结构 我尝试了以下课程: Class TreeNode { String name TreeNode parent static hasMany = [children: TreeNode] //returns the root nod

我想在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

树通常每个节点有一个父节点。您可以定义与自身具有一对多关系的树节点,如下所示:

class TreeNode {
    TreeNode parent
    static hasMany = [children: TreeNode]
    static mappedBy = [children: 'parent']
}
class GraphNode {
    static hasMany = [children: GraphNode]
    static hasMany = [parents: GraphNode]
    static mappedBy = [children: 'parents', parents: 'children']
}
如果它有多个父母,它实际上不是计算机科学意义上的树。这种数据结构通常称为有向图。您可以将其建模为与自身的多对多关系,如下所示:

class TreeNode {
    TreeNode parent
    static hasMany = [children: TreeNode]
    static mappedBy = [children: 'parent']
}
class GraphNode {
    static hasMany = [children: GraphNode]
    static hasMany = [parents: GraphNode]
    static mappedBy = [children: 'parents', parents: 'children']
}

阿泰洛是对的。要描述关系,必须使用2个域类:

class Node {
    static hasMany = [relations: Relation]
}
class Relation {
    Node fromNode
    Node toNode
    String name //ex. 'son'
    String reverseName // ex. 'father'
}

如何插入和删除节点?如何扩展与属性(如dateCreated)的关系?插入和删除,与任何其他grails域对象相同。在
GraphNode
示例中,调用
node.addToParents(parent)
node.addToChildren(child)
在保存前添加父级或子级。如果希望关系本身具有属性,最好将关系建模为单独的实体,例如,
GraphNode
GraphEdge
。添加
mappedBy
告诉gorm
children
是通过
parent
映射的。这不起作用,因为我的类与您发布的不同。将此添加到您发布的类:
static mappedBy=[children:'parent']
。@tim_yates的可能重复并非同一主题的每个问题都是重复的!我认为,您需要添加'static belongsTo=[parent:TreeNode]'