Уникальный тест Grails не пройден после обмена значениями атрибутов - PullRequest
0 голосов
/ 30 мая 2011

Здравствуйте. Я пытаюсь реализовать простой список перевода, то есть у меня есть значения и переводы к этим значениям.

[Edit:] Поскольку это часть моего пользовательского интерфейса, значения и переводы можно экспортировать через xml, используя швы файлов i18n, что довольно неудобно для этого предложения. Вот почему я решил сохранить их в базе данных.

У меня есть один класс домена для значения:

class Value {
    String label
    static hasMany = [ translations: Translation ]
}

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

class Translation {
    String value
    Language language

    static belongsTo = [ value: Value ]

    static constraints = {
        language(unique: 'value')
    }
}

Моя проблема возникает после замены двух языков перевода на одно и то же значение. Пример:

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// process updates...

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// validate...

распечатывает

Comedy in german: Comedy
Comedy in english: Komödie   

Comedy in english: Comedy
Comedy in german: Komödie

поэтому уникальное ограничение не нарушается до и после обновления, но в любом случае при сохранении возникает ошибка уникального ограничения. Другая странная вещь заключается в том, что я получаю эту ошибку, только когда выполняю цикл each () для значения. Если я не проверяю содержимое, проверка проходит, и метод save (flush: true) возвращает true, но значения не будут изменены в базе данных.

[Edit:] Я считаю, что проблема на уровне базы данных, когда изменяется только одно значение, а другое нет, потому что именно в этом состоянии ограничение нарушается. Если изменения будут выполнены как транзакция, а ограничения не будут проверены на этом промежуточном этапе, этого можно избежать. (это может быть вещь, которую я ищу)

Другим способом избежать этого было бы удаление и воссоздание каждого отредактированного компонента, но я надеялся, что может быть более удобный способ сделать это.

Спасибо за любую помощь

1 Ответ

1 голос
/ 30 мая 2011

Ограничение проверяется, когда происходит неявное или явное flush().В этот момент GORM проверяет, существует ли другое такое значение в базе данных .Таким образом, если один экземпляр уже flush() ed, а другой еще нет, вы получите нарушение ограничения.

Старайтесь не flush() до конца транзакции - удалите параметр flush: true или дажеустановите его на flush: false.В конце транзакции должны применяться оба изменения.

В Grails, JFYTK, есть предостережение: при выполнении Criteria неявное flush(), поэтому не слишком удивляйтесь ошибкам Hibernate, когда выпока не собирался flush().

...