Am using grails 2.0.3 with default h2 database and have the following user domain class:
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)
}
}
In the controller, I save the user using the following code:
userInstance.save(flush: true)
Now, this afternoon, I realized that the password field should have a size constraint and hence modified the domain class so that it became as follows (only change is in the constraints):
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)
}
}
Subsequently I generated the views and controllers again. Now when I am trying to save the user object from the controller, using:
userInstance.save(flush: true)
I am getting the following exception:
Class: org.hibernate.AssertionFailure Message: null id in login.User entry (don't flush the Session after an exception occurs)
Any help will be appreciated.
Info: If I remove the size constraint from the new/modified class the saving happens fine.
I ran into the same problem using Grails 3.1.12. This is what I found out and how I solved it.
Problem:
You are trying to put a size constraint to a field that is going to be enconded. This means that a password like "admin5" will turn at the end of the domain life cycle as an encoded pwd. For example the db will stored the pwd as: "$2a$10$dn7MyN.nsU8l05fMkL/rfek/d1odko9H4QUpiNp8USGhqx9g0R6om".
The validation process will apply the size constraint to the unencoded pwd (validation step on the domain life cycle), wich will pass because the pwd typed by the user is in that range. but on the save() method (persistance step on the domain life cycle) the pwd will be encoded before an insert or update. The enconding method will create a pwd with a size bigger than your constraint and Hibernate will fail the assert() for the pwd size.
Solution:
Use the minSize constraint if you don't need to worry about the maxSize
static constraints = {
password blank: false, minSize:6
}
If you need to validate the maxSize, then I recommend you do the validation on your Service or Controller layer before creating the domain instance.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.