Грааль добавить дубликаты
У меня установлена следующая ассоциация:
class Applicant {
String appStepsComplete
String name
String eNumber
String email
String homePhone
String cellPhone
String address
Integer age
static hasMany = [scholarships:Scholarship]
static mapping = {
scholarships joinTable: [name:"APPLICANT_SCHOLARSHIPS"]
}
}
class Scholarship {
String fundCode
String seqNo
String name
static belongsTo = Applicant
}
Когда я звоню, это позволяет добавлять дубликаты в базу данных:
applicant.scholarships << schol
applicant.save()
Мне это нужно для предотвращения дубликатов в базе данных. Я попытался установить уникальное ограничение на стипендии для заявителя, выполнив следующие действия, но это не сработало:
static constraints = {
scholarships(unique:true)
}
1 ответ
Комментарий Берта Беквита верен, вам нужно переопределить hashCode и равноценный стипендии. Предполагая, что бизнес-ключ (комбинация полей, которые однозначно идентифицируют эту сущность, которые вы использовали бы в качестве составного естественного ключа, если база данных не использовала искусственный идентификатор) для этого, представляет собой комбинацию fundCode и seqNo, у вас может быть что-то вроде:
int hashCode() {
(fundCode + seqNo).hashCode()
}
boolean equals(Object other) {
other?.getClass() == this.class
&& other.fundCode == fundCode
&& other.seqNo == seqNo
}
Реализация hashCode, вероятно, не самая эффективная вещь, это ленивый способ сделать это, опираясь на hashCode String. Но достаточно сказать, решает ли это проблему дурака.
Решение DRYer заключается в использовании преобразования AST с этой аннотацией
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode(includes=['fundCode', 'seqNo'])
class Scholarship {
String fundCode
String seqNo
String name
static belongsTo = Applicant
}
который сгенерирует для вас методы equals и hashCode.
Реализация Set полагается на эти методы, чтобы решить, представляют ли два экземпляра объекта одну и ту же информацию. Не переопределение означает, что единственная проверка заключается в том, являются ли ссылки одинаковыми (поэтому в случае, когда у вас есть разные экземпляры объектов, которые имеют одинаковую информацию, они будут рассматриваться как два разных объекта). Использование бизнес-информации вместо идентификатора для проверки равенства означает, что она будет работать независимо от того, назначены ли доменным объектам идентификаторы.