Am使用grails 2.0.3和默认的h2数据库,并具有以下用户域类:
class User {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Preferences preferences
Company company
Personal personal
static constraints = {
username email: true, blank: false, unique: true
password blank: false
preferences unique: true
company unique: true
personal unique: true
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
在控制器中,我使用以下代码保存用户:
userInstance.save(flush: true)
现在,今天下午,我意识到密码字段应该有一个大小约束,因此修改了域类,使其变成如下(唯一的变化是约束):
class User {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Preferences preferences
Company company
Personal personal
static constraints = {
username email: true, blank: false, unique: true
password blank: false, size: 6..15
preferences unique: true
company unique: true
personal unique: true
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
随后,我再次生成了视图和控制器。现在,当我试图从控制器保存用户对象时,使用:
userInstance.save(flush: true)
我得到以下异常:
类:org.hubinate.AssertionFailure消息:登录id为空。用户输入(发生异常后不要刷新会话)
任何帮助都将不胜感激。
信息:如果我从新的/修改的类中删除大小约束储蓄是好事。
我在使用Grails 3.1.12时遇到了同样的问题。这就是我发现的,以及我是如何解决的。
问题:
您正试图对将被编码的字段设置大小约束。这意味着像"admin5"这样的密码将在域生命周期结束时变成编码的pwd。例如,数据库将pwd存储为:"$2a$10$dn7MyN.nsU8l05fMkL/rfek/d1odko9H4QUpiNp8USHqx9g0R6om"。
验证过程将对未编码的pwd应用大小约束(域生命周期中的验证步骤),由于用户键入的pwd在该范围内,因此验证将通过。但是在save()方法(域生命周期中的持久步骤)中,pwd将在插入或更新之前进行编码。enconding方法将创建一个大小大于约束的pwd,Hibernate将使该pwd大小的assert()失败。
解决方案:
如果您不需要担心maxSize ,请使用minSize约束
static constraints = {
password blank: false, minSize:6
}
如果您需要验证maxSize,那么我建议您在创建域实例之前对服务或控制器层进行验证。