简体   繁体   中英

Grails domain class constraint modification causing exception

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM