2015-08-07 3 views
0

Имея случай, когда область была собственностью себя, как показано ниже:Grails домен класс множественного циклическая ссылка вопрос

Group{ 
    String name 
    Role role 
    static belongsTo=[boss:Group] 
    static hasMany=[children:Group,supporters:Group] 
} 

static constraint={ 
    boss nullable:true 
    supporters validator: {supporters, group-> 
      supporters?.each {Group supplier -> 
       if(!(supporters.role == Role.OPS)){ 
        return "domain.not.supporters.object" 
       } 
      } 
      return true 
     } 
} 
} 

Role{ 
    MANAGER,LEADER,DEVELOPERS,OPS 
} 

Над сторонницы с ролевым OPS, для которых мы добавили проверку, а также. Общие сторонники не подпадают под оригинал Manager>Leader>Developer hierarchy.

Теперь, когда я создаю несколько объектов групп детей, скажите MANAGER_RAD > LEAD_BAD ->(DEV_JACK and DEV_MOHAN) и сторонники предоставляются только Менеджерам. Код ниже заставит понять сценарий:

Group manager = new Group(name:'MANAGER_RAD') 
manager.addToSupporters(new Group(name:'OPS_BISK').save(flush:true)) 
manager.addToSupporters(new Group(name:'OPS_BAHADUR').save(flush:true)) 
Group lead = new Group(name:'LEAD_BAD').save(flush:true) 
lead.addToChildren(new Group(name:'DEV_JACK').save(flush:true)) 
lead.addToChildren(new Group(name:'DEV_MOHAN').save(flush:true)) 
lead.save(flush:true) 
manager.addToChildren(lead) 
manager.save() 

Теперь, когда мы пытаемся получить детей менеджера следующим образом (скажем, в нашем загрузчике):

Group manager = Group.findByName('MANAGER_RAD') 
println "------Manager team members---->$manager.children" 
println "------supporters for Manager---->$manager.supporters" 

Ожидаемый результат:

------Manager team members---->[LEAD_BAD(id:2)] 
------supporters for Manager---->[OPS_BAHADUR(id:7),OPS_BISK(id:7)] 

Но выход возвращается:

------Manager team members---->[LEAD_BAD(id:2),OPS_BAHADUR(id:7),OPS_BISK(id:7)] 
------supporters for Manager---->[LEAD_BAD(id:2),OPS_BAHADUR(id:7),OPS_BISK(id:7)] 

Как получить ожидаемый результат.

Любая помощь будет стоить.

+0

Возможно, вы потеряли свойство 'mappedBy'. См. Https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/mappedBy.html. – defectus

+0

Я тоже пытался с mappedBy, но напрасно. –

+0

Приятно видеть, что я был прав (угадывая, что вы принимаете ответ, предполагающий использование свойства mappedBy) :-) – defectus

ответ

2

Поскольку ваш код имеет собственное ссылочное свойство (boss), а также две разные свойства ассоциации того же типа, Grails не может создать правильную схему.

От Grails документы:

Иногда вы можете найти себя с доменными классами, которые имеют несколько свойств одного и того же типа. Они могут даже быть self-referential, т. Е. Свойство ассоциации имеет тот же тип, что и , класс домена, в котором он находится. Такие ситуации могут вызвать проблемы, потому что Grails может неправильно предположить тип ассоциации.

В вашем случае Grails генерирует одну таблицу и ваших детей и сторонников свойства быть связываются с boss_id столбец в схеме.

Чтобы преодолеть эту ситуацию, вы можете использовать mappedBy и указать имена свойств для свойств детей и сторонников, которые будут привязаны к именам свойств.

После изменения ваш класс домена будет выглядеть следующим образом:

class Group { 
    String name 
    Role role 

    static belongsTo = [boss: Group] 
    static hasMany = [children: Group, supporters: Group] 

    static mapping = { 
     table 'groups' 
    } 

    static mappedBy = [children : "none", 
         supporters: "none"] 

    static constraints = { 
     boss nullable: true 
     role nullable: true 
     supporters validator: { supporters, group -> 
      supporters?.each { Group supplier -> 
       if (supporters.role != Role.OPS) { 
        return "domain.not.supporters.object" 
       } 
      } 
      return true 
     } 
    } 

} 

enum Role { 
    MANAGER, LEADER, DEVELOPERS, OPS 
} 

Теперь Grails сгенерирует две таблицы для вас: группы и groups_groups. Если вы пропустите mappedBy для любого из свойств, это свойство будет связываться с 'boss_id' column в groups table.

Структура groups_groups таблица будет:

+-------------------+----------+---------------------+ 
| group_children_id | group_id | group_supporters_id | 
+-------------------+----------+---------------------+ 

см https://grails.github.io/grails-doc/latest/guide/GORM.html#domainClasses для более подробного объяснения.

Смежные вопросы