static constraints = {<br> dealerID nullable:true;<br> carID unique:'dealerID', blank:false;<br> tyreID unique:'carID';<br>}<br>
Это не будет работать как задумано. Это сделает carID уникальным только в рамках авизо дилера. tyreID будет уникальным в рамках «carID». Это означает, что при вводе этой совершенно правильной строки проверка не будет выполнена:
CarID TyreID DealerID
01 02 NULL Existing row
01 02 95 New row is rejected
Это потому, что TyreID не уникален - он конфликтует с существующим CarID. Мы хотим, чтобы уникальное ограничение применялось к области действия всех указанных полей
Насколько я знаю, эта проблема все еще существует в последней версии Grails (1.3.7)
Это мой обходной путь
В своем доменном классе напишите пользовательский валидатор для поля, которое ищет существующую запись, используя CriteriaBuilder:
class MyClass {
...
static constraints = {
...
carID( validator: { Integer carID, MyClass thisInstance ->
def existingRecord = MyClass.withCriteria(uniqueResult:true){
ne('id', thisInstance.id)
if (thisInstance.tyreID) {
eq('tyreID', thisInstance.tyreID)
}
else {
isNull('tyreID')
}
if (thisInstance.dealerID) {
eq('dealerID', thisInstance.dealerID)
}
else {
isNull('dealerID')
}
})
if (existingRecord) {
return ['myClass.duplicate', existingRecord.id]
}
else {
return true
}
}
)
и в свойствах вашего сообщения вы можете предупредить пользователя, что эта запись конфликтует с определенной записью:
message.properties
...
myClass.duplicate = {0} is identical to existing record {3}
Это хакерское решение, требующее потенциально ненужного попадания в базу данных и выглядит безобразно. Мне это не нравится, но это работает.