Grails addTo 重复项

标签 grails groovy unique relationships jointable

我建立了以下关联:

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)
}

最佳答案

Burt Beckwith 的评论是正确的,您需要在奖学金上覆盖 hashCode 和 equals。假设业务键(唯一标识该实体的字段组合,如果数据库不使用人工 id,则将其用作复合自然键)是 fundCode 和 seqNo 的组合,您可以有类似的东西:

int hashCode() {
    (fundCode + seqNo).hashCode()
}

boolean equals(Object other) {
    other?.getClass() == this.class
    && other.fundCode == fundCode 
    && other.seqNo == seqNo
}

hashCode 实现可能不是有史以来性能最好的东西,它是一种懒惰的方式,依赖于 String 的 hashCode。但这足以说明它是否解决了欺骗问题。

DRYer 解决方案是使用带有此注释的 AST 转换
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode(includes=['fundCode', 'seqNo'])
class Scholarship {
    String fundCode
    String seqNo
    String name

    static belongsTo = Applicant
}

这将为您生成 equals 和 hashCode 方法。

Set 实现依赖于这些方法来决定两个对象实例是否表示相同的信息。不覆盖意味着唯一检查引用是否相同(因此,如果您有具有相同信息的不同对象实例,它们将被视为两个不同的对象)。使用业务信息而不是 id 来检查相等性意味着无论域对象是否分配了 id,它都会起作用。

关于Grails addTo 重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28072049/

相关文章:

c - C中的非重复数字数组?

spring - Grails 3 Spring 安全插件

grails - 如何以Groovier方式查询?

grails gsp g :set counter problem

java - 我们如何迁移/更新 Grails 中的数据库模式?

python - Groovy 脚本无法执行外部进程

php - 从目录中随机选择两个(唯一的)图像

matlab - 删除相邻的重复项

Grails - 从另一个租户检索对象

java - chalice 。使用@GrailsCompileStatic时如何处理 'mixed'方法和变量