Grails addTo重复

时间:2015-01-21 16:23:49

标签: 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)
}

1 个答案:

答案 0 :(得分:2)

Burt Beckwith的评论是对的,你需要覆盖hashCode并等于奖学金。假设业务密钥(唯一标识此实体的字段的组合,如果数据库不是使用人工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,它都将起作用。