grails,hasMany,set和duplicatelicates

时间:2014-02-03 09:13:37

标签: grails gorm

grails文档说默认情况下hasMany是一个集合。 我的域名如下:

class Employee {
    String name;
    String empId;
    String password;
    String contactNumber;
    String emailId;

    static hasMany = [roles : Role]

    static belongsTo = [department : Department]

    static constraints = {
        contactNumber nullable : true
        emailId nullable : true
        empId unique : true
        roles nullable : true
        department nullable : true
    }

    static mapping = {
        sort name : "asc"
    }
}

//Role class
class Role {
    String role;
    String roleId;
}

控制器中的以下代码允许向“角色”添加重复的条目:

roleListToBeAdded.each { r ->
                        println "Trying to add ${r}"
                        try {
                            employee.addToRoles(r).save(flush:true)
                        } catch (Exception e) {
                            println "failed to add ${r}: ${e}"
                        }
                    }

为什么会这样?

注意:如果 roleListToBeAdded 有多个相同角色的条目(例如:如果请求JSON如下所示:{“rolesToBeAdded”:[{“role”:33},{“role “:33}})然后它没有添加两次,但是如果已经添加了角色33并且我再次使用角色33发出新请求,那么它会在'employee_role'表中再添加一条记录。

2 个答案:

答案 0 :(得分:1)

您需要向Role类添加适当的equalshashCode,因为Set uniqueness基于Java相等而不是数据库标识。 equals定义应基于数据(例如角色名称)而不是数据库ID,因为“瞬态”实例(尚未保存的实例)具有空ID。

答案 1 :(得分:-1)

我认为问题不仅出现在“Set”或“equals”或“hashcode”实现中,而且出现在Role类中。这个班级

class Role {
    String role;
    String roleId;
}

在这个类中有两个id:第一个是'roleId',但它不是主键。实际上,如果您希望'roleId'是PK,则必须向Role类添加静态映射(请点击此帖Stack Post, 10120708):

 class Role {
    String role;
    String roleId;
    static mapping = {
       id column: 'roleId', type: 'varchar'
    }
 }

如果未设置此映射,则会将隐式PK定义为“id”(第二个:))。如果你看到grails框架创建阅读'Role'类的表,你会看到如下内容:

TableName Role
id(This is PK)           role           roleId
---                      ---            ---

这就是为什么equals / hashcode默认方法似乎不起作用,它们在隐式id之间进行比较,而不是在roleId之间进行比较。

再见