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。