2016-12-20 11 views
0

У меня есть то, что я думал, был простой hasMany ассоциации - это UserGroup hasMany пользователей и UserGroup является собственностью пользователя:Grails 3 beforeInsert() не останавливает связанные вставки?

class UserGroup { 

    String name 
    User owner 
    Set members = [] 
    static hasMany = [members: User] 
    ... 
} 

Fine до сих пор. Я хотел, чтобы имя было уникальным для каждого владельца, поэтому изначально поставил ограничение на имя:

name unique: 'owner' 

Однако это также предотвращено обновления одного и того же имени. Таким образом, я переместил ограничение на beforeInsert и выполнить логику expicitly:

def beforeInsert() { 
    boolean existing = false 
    UserGroup.withNewSession { 
     existing = UserGroup.where { 
      owner == this.owner && name == this.name 
     }.count() > 0 
    } 
    if (existing) { 
     this.errors.rejectValue(...) 
    } 
    return !this.hasErrors() 
} 

При сохранении нового объекта UserGroup с членами, и beforeInsert проходит, я вижу действие Гибернации а) вставить UserGroup тогда б) вставить элементы ,

При сохранении нового объекта UserGroup с членами и beforeInsert сбой из-за дублирующегося имени, я вижу только действия спящего режима для вставки членов. Это не так, потому что нет родительской записи.

Я делаю что-то неправильно, или это правда, что beforeInsert только убивает часть операции save(), а не все это? И что делать?

+0

Как я уже сказал, мне не нужен какой-либо специальный код, так как исправленное обновление не нарушает ограничение уникальности. Итак, проблема исчезла, но поведение beforeInsert(), я думаю, все еще вызывает сомнения. – Jay

+0

При сохранении нового объекта UserGroup с членами и beforeInsert сбой «из-за дублирующегося имени». Это не так, потому что существует «родительская запись». Почему у вас нет родителя? это было потому, что оно попало в beforeInsert как «дубликат», как вы предложили. Не уверен, что ваш текущий вопрос имеет какое-либо значение. Так как даже если у него есть родитель, которого он не может из-за того, что он является дубликатом, ему придется откатить обе таблицы вместо 1, как сейчас – Vahid

ответ

0

Этот код на beforeInsert должен быть на пользовательском валидаторе, но он проверяет уникальное имя, поэтому правильное ограничение должно быть просто уникальным: true (не уверен, какое имя уникально: «владелец» делает, поскольку он недействителен , то значение должно быть булево как в спецификации https://docs.grails.org/latest/guide/validation.html)

И если вы хотите, чтобы пользователи в группе, чтобы быть сохраненным в каскаде, которые могут быть заданы в области отображения, как указано на документы https://docs.grails.org/latest/ref/Database%20Mapping/cascade.html

Если пользовательский валидатор выходит из строя, или только уникальный сбой, каскадное сохранение/обновление не должно выполняться.