Грааль добавить дубликаты

У меня установлена ​​следующая ассоциация:

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 полагается на эти методы, чтобы решить, представляют ли два экземпляра объекта одну и ту же информацию. Не переопределение означает, что единственная проверка заключается в том, являются ли ссылки одинаковыми (поэтому в случае, когда у вас есть разные экземпляры объектов, которые имеют одинаковую информацию, они будут рассматриваться как два разных объекта). Использование бизнес-информации вместо идентификатора для проверки равенства означает, что она будет работать независимо от того, назначены ли доменным объектам идентификаторы.

Другие вопросы по тегам