Сбой проверки Grails после обмена уникальными значениями атрибута
Привет, я пытаюсь создать интерфейс, в котором пользователи могут создавать некоторые пользовательские перечисления с переводами для разных языков. Например, пользователь может создать перечисление «Жанр фильма». Для этого перечисления может существовать перечисление-значение "Комедия", для которого может существовать один или несколько перечислений-значений-переводов для нескольких языков.
Поскольку для определенного языка должен быть только один перевод, я добавил уникальное ограничение в класс домена перечисления-значения-перевода. Это мои доменные классы прямо сейчас:
class Enumeration {
String label
List<EnumerationValue> enumerationValues = new ArrayList<EnumerationValue>()
static hasMany = [ enumerationValues: EnumerationValue ]
static constraints = {
label(nullable: false, blank: false)
enumerationValues(nullable: true)
}
}
class EnumerationValue {
String label
List<EnumerationValueTranslation> enumerationValueTranslations = new ArrayList<EnumerationValueTranslation>()
static belongsTo = [ enumeration: Enumeration ]
static hasMany = [ enumerationValueTranslations: EnumerationValueTranslation ]
static constraints = {
label(nullable: false, blank: false, unique: 'enumeration')
enumeration(nullable: false)
enumerationValueTranslations(nullable: false)
}
}
class EnumerationValueTranslation {
String value
Language language
static belongsTo = [ enumerationValue: EnumerationValue ]
static constraints = {
value(nullable: false, blank: false)
language(nullable: true, unique: 'enumerationValue')
enumerationValue(nullable: false)
/* unique constraint as mentioned in description text */
language(unique: 'enumerationValue')
}
}
Пока это работает довольно хорошо. Моя проблема возникает, когда я обновляю два перечисления-значения-значения одного и того же значения-перечисления способом, которым обмениваются языки. Например, у меня есть
- перечисление-значение: "Комедия"
и некоторые переводы, где язык "случайно" перепутан
- переводы для "Comedy"
- язык: немецкий, значение: "комедия"
- язык: английский, значение "Komödie"
если пользователь узнает, что он перепутал язык, он может захотеть поменять языки и снова сохранить перечисление. И именно здесь происходит моя ошибка, потому что после замены языков уникальное ограничение перечисления-значения-трансляций становится ложным.
Чтобы отладить это, я просто попытался распечатать ошибку, вызывающую переводы до и после обработки параметров, поэтому:
Enumeration enumeration = Enumeration.get(params['id']);
println "before:"
enumeration.enumerationValues.each() { enumValue ->
enumValue.enumerationValueTranslations.each() { enumValueTr ->
println enumValueTr;
if(!enumValueTr.validate()) {
// print errors...
}
}
}
// swap languages:
// (this are the lines of codes that are actually executed, and cause the
// error. The actual processing of params looks different of course...)
// sets the language of "Comedy" to English
EnumerationValueTranslation.get(5).language = Language.get(1);
// sets the language of "Komödie" to German
EnumerationValueTranslation.get(6).language = Language.get(2);
println "after:"
enumeration.enumerationValues.each() { enumValue ->
enumValue.enumerationValueTranslations.each() { enumValueTr ->
println enumValueTr;
if(!enumValueTr.validate()) {
// print errors...
}
}
}
который приводит к:
before:
EnumerationValueTranslation(value: Fantasy, language: en_US, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Phantasie, language: de_DE, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Comedy, language: de_DE, enumerationValue: Comedy)
EnumerationValueTranslation(value: Komödie, language: en_US, enumerationValue: Comedy)
after:
EnumerationValueTranslation(value: Fantasy, language: en_US, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Phantasie, language: de_DE, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Comedy, language: en_US, enumerationValue: Comedy)
validation fails: Property [language] of class [Translation] with value [Language(code: en_US)] must be unique
EnumerationValueTranslation(value: Komödie, language: de_DE, enumerationValue: Comedy)
validation fails: Property [language] of class [Translation] with value [Language(code: de_DE)] must be unique
в этом состоянии я не удалил, или сохранил (или каким-либо образом очищен) что угодно - это всего лишь результат после изменения объектов. И, как вы можете видеть, в реальных данных нет несоответствий, и проверка не должна завершиться неудачей.
Может ли быть ошибка в том, как я меняю переводы? Я просто выбрал их по идентификатору и просто обновил язык - я попробовал это на минималистичном примере, и это сработало там ...
Это также работает, если я просто создаю глубокую копию всех перечислений-значений и перечислений-значений-преобразований и сохраняю их вместо этого (что означает, что проверка действительно не должна завершиться ошибкой), но я думаю, что это действительно не так, как должно быть сделано ...
Другая странная вещь заключается в том, что валидация завершается неудачей, только если я перебираю данные Если я вообще не касаюсь данных, ошибки не возникает, но данные также не сохраняются, а это означает, что следующие строки приводят к тому, что проверки проверяются вообще:
enumeration.enumerationValues.each() { ev ->
ev.enumerationValueTranslations.each() { evt ->
}
}
, поэтому я твердо верю, что должна быть какая-то нетривиальная проблема ... пожалуйста, дайте мне знать, если есть что-то еще, что вам нужно знать.
спасибо за любую помощь