Validation Grials更新因唯一约束而失败

Validation Grials更新因唯一约束而失败,validation,grails,constraints,unique,Validation,Grails,Constraints,Unique,我有一个用户域,在该域中,我对其员工编号有唯一的限制 class User { Integer employeeNumber String employeeLogin String firstName String middleName String lastName String nickname Date birthday static mapping = { table 'user' id

我有一个用户域,在该域中,我对其员工编号有唯一的限制

class User {

    Integer employeeNumber
    String employeeLogin
    String firstName
    String middleName
    String lastName
    String nickname
    Date birthday

    static mapping = {
        table 'user'
        id generator: 'assigned', name: 'employeeNumber', type: 'int'
        employeeNumber column: 'employee_number'
        version false
        sort 'lastName'
    }

    static constraints = {
        employeeNumber(blank: false, nullable: false, unique: true)
        employeeLogin(blank: false, nullable: false, unique: true)
        firstName(blank: false, nullable: false)
        middleName(blank: true, nullable: true)
        lastName(blank: false, nullable: false)
        nickname(blank: true, nullable: true)
        birthday(blank: true, nullable: true)
    }
}
我正在尝试用

class UserController {

    ...

    def saveUser() {

    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");

        if (params.userId) { // handles user update for existing employeeNumber
            def user = User.findByEmployeeNumber(params.userId) // sent in hidden field name userId with value employeeNumber

            user.employeeNumber = Integer.parseInt(params.employeeNumber)
            user.employeeLogin = params.employeeLogin
            user.firstName = params.firstName
            user.middleName = params.middleName
            user.lastName = params.lastName
            user.nickname = params.nickname
            try {
                user.birthday = formatter.parse(params.birthday)
            } 
            catch (Exception ignore) {
                user.birthday = null
            }

            if (user.validate()) {
                user.save(flush:true, failOnError:true)
                redirect(action:'profile', id:user.employeeNumber)
            } else {
                render(view:'editUser', model:[user:user])
            }
        } else {  // handles new user
            ... // this part works
        }
    }

    ...

}
但是由于
employeeNumber
employeeLogin
上的独特约束,if(user.validate()){…}正在流行


创建新用户时,我希望用户名和id是唯一的,但在更新时,我显然希望更新现有用户,但是这个唯一的约束阻止了我这样做。关于如何解决此问题,您有什么想法吗?

您遇到此错误是因为您将employeeNumber字段作为主键

对于Hibernate/Grails,主键是对象的标识符值。它是在对象的生命周期中永远不会改变的东西

在更新过程中,您试图修改导致问题的标识符

您完全可以修改一个唯一的字段,因此在您的情况下,您可以修改employeeLogin。但是您不能修改主键


另外,employeeNumber已经是主键,因此不要将其声明为唯一键。这将删除您所面临的唯一密钥错误。

hum如果出现问题,请查找用户并找到它,然后更新其密钥。正常的系统是不快乐的;如果你能找到用户,为什么你要设置employeeNumber和employeeLogin(因此这些值首先存在,因为你可以创建它)-你应该从块中删除这两行Frederic,我同意你的建议。这类问题变成了“我们应该”而不是“我们可以”的问题。我将保留验证,以便新用户具有唯一的用户名和id,但要确保一旦创建了用户名和id,就不能修改这两个字段。谢谢弗雷德里克,我同意你的建议,但我还是有同样的错误。我完全删除了
user.employeeNumber=Integer.parseInt(params.employeeNumber)
user.employeeLogin=params.employeeLogin
,但仍然会抛出唯一约束。那么,如何执行更新呢?根据弗雷德里克的建议,我删除了
user.employeeNumber=Integer.parseInt(params.employeeNumber)
user.employeeLogin=params.employeeLogin
,但是,当它尝试验证时,仍然会抛出唯一约束从
employeeNumber
删除唯一约束会消除该约束验证错误,但是值为[pwillad]的类[class User]的
属性[employeeLogin]必须是唯一的
仍然看起来很好,这似乎是Grails的一个问题。作为一种解决方法,您可以为employeeLogin字段编写自己的自定义唯一验证程序,并删除默认的唯一约束。此外,从employeeNumber中删除唯一约束允许新用户信息覆盖用户信息,因此,该约束也是必须的。Grails似乎没有在分配主键的情况下很好地处理唯一约束。因此,如果您不是使用遗留数据库构建应用程序,我会说您应该使用默认生成的id字段作为PK。