New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GORM persistence listener invokes PreUpdate on insert #885

Closed
jameskleeh opened this Issue Mar 1, 2017 · 4 comments

Comments

Projects
None yet
3 participants
@jameskleeh
Copy link
Contributor

jameskleeh commented Mar 1, 2017

A GORM event listener with the following method:

    @Override
    protected void onPersistenceEvent(AbstractPersistenceEvent event) {
        if (event.entityObject instanceof User) {
            User user = (User)event.entityObject
            if (user.password) {
                if (event.eventType == EventType.PreInsert || user.isDirty('password')) {
                    user.password = springSecurityService.encodePassword(user.password)
                }
            }

        }
    }

The line that sets the password on the user object causes 2 further PreUpdate events to fire, even though the object is new

new User('foo', 'bar').save()

Example project: https://github.com/jameskleeh/test-gdm-885

To reproduce, run the app

@jameskleeh

This comment has been minimized.

Copy link
Contributor

jameskleeh commented Mar 1, 2017

Just to note I also attempted modifying the domain with event.entityAccess with the same result

@jameskleeh

This comment has been minimized.

Copy link
Contributor

jameskleeh commented Mar 1, 2017

Another note - I attempted to do the same thing with hibernate event listeners and also got the same result. beforeInsert() in the domain class works as expected

@sdelamo

This comment has been minimized.

Copy link
Collaborator

sdelamo commented Apr 4, 2017

I believe I am experiencing this issue as well. When doing findByUsername, I am getting an event PreUpdate with password dirty. See:

https://github.com/sdelamo/grails-spring-security-core/blob/abstractPersistenceEventListener/functional-test-app/src/integration-test/groovy/com/testapp/TestUserServiceIntegrationSpec.groovy#L31

@graemerocher graemerocher added this to the 6.1.1 milestone Apr 4, 2017

graemerocher added a commit to grails/gorm-hibernate5 that referenced this issue Apr 5, 2017

graemerocher added a commit that referenced this issue Apr 5, 2017

@graemerocher graemerocher modified the milestones: 6.0.10, 6.1.1 Apr 5, 2017

graemerocher added a commit that referenced this issue Apr 5, 2017

@graemerocher

This comment has been minimized.

Copy link
Member

graemerocher commented Apr 5, 2017

So just to summarise, there is no direct solution to this, using an objects setter, however you can use the EntityAccess object. So the example here becomes

event.getEntityAccess().setProperty("password", springSecurityService.encodePassword(user.password))

With this change, GORM will sync the state with Hibernate and no additional update will be triggered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment