Древовидная структура в Горме (граали)


Я пытаюсь определить древовидную структуру в GORM. Вот моя модель:

class Tree {
    String name
    Level rootLevel

    static hasOne = [rootLevel: Level]
    static hasMany = [levels: Level]
    static mappedBy = [levels:"parentTree"]
}

class Level {
    String name
    Tree parentTree
    Level parentLevel
    Set<Level> subLevels

    static belongsTo = [parentTree: Tree]
    static hasMany = [subLevels: Level]
}
Вставка, кажется, работает нормально, но когда я не могу загрузить дерево со многими уровнями и подуровнями. Наверное, я что-то упустил в отношениях: - дерево должно иметь ссылку на корневой уровень (и необязательно на все подуровни) - уровень должен иметь ссылку на его Родительский уровень, его подуровни и глобальное родительское дерево

Не могли бы вы указать мне правильное направление, чтобы получить такую древовидную структуру, как эта ? Спасибо

3 3

3 ответа:

Мне не понравилась ваша древовидная структура, поэтому я создал свою собственную :)

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()
    }
}

Что касается обеспечения загрузки всех treenodes, вы всегда можете использовать нетерпеливую/не ленивую выборку для каждого treeNode как родительского, так и дочернего. Однако это может привести к снижению производительности, если ваши древовидные структуры очень велики...

А для нетерпеливых/ленивых выборки. посмотрите здесь: Использование ленивой выборки свойств в Grails / Gorm

Проблема заключается в том, что уровни заполняются идентификатором родительского дерева, но при загрузке дерева возникает следующая ошибка "для класса Level найдено более одной строки с заданным идентификатором".

Ваша проблема, похоже, заключается в том, что у вас есть более одного корневого узла для каждого дерева. Это необычный подход. Чтобы заставить его работать, вы должны заменить Level rootLevel в сущности Tree на Set<Level> roots.

Я пришел к такому решению (спасибо другу):

class Tree {
   String name
   Level rootLevel

   static hasMany = [levels: Level]
   static mappedBy = [rootLevel: "parentTree", levels: "owningTree"]

   static constraints = {rootLevel(nullable: true)}
}

И

class Level {
   String name
   Tree parentTree
   Tree owningTree
   Level parentLevel
   Set<Level> subLevels

   static belongsTo = [owningTree: Tree, parentLevel: Level]
   static hasMany = [subLevels: Level]
   static mappedBy = [parentTree: "rootLevel", owningTree: "levels", subLevels: "parentLevel"]

   static constraints = {
       parentTree(nullable: true)
       parentLevel(nullable: true)
   }
}

Мне не хватало двух отношений между деревом и уровнем (owningTree и parentTree) и некоторой конфигурации mappedBy, помогающей гибернации.