Древовидная структура в ГОРМ (грааль) - PullRequest
3 голосов
/ 04 мая 2011

Я пытаюсь определить древовидную структуру в 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]
}

Кажется, что вставка работает нормально, но когда я не могу загрузить дерево с множеством уровней и подуровней. Наверное, я что-то упустил в отношениях - Дерево должно иметь ссылку на rootLevel (и, необязательно, на все подуровни) - уровень должен иметь ссылку на его родительский уровень, его подуровни и глобальное родительское дерево

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

Ответы [ 3 ]

11 голосов
/ 04 мая 2011

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

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

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

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

0 голосов
/ 06 мая 2011

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

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

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

0 голосов
/ 04 мая 2011

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

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

...