Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 42fac44

Browse files
authored
Fixes issue to save state changes from the listener (#173)
* apache/grails-data-mapping#1265 Hibernate5 test to update from the AbstractPersistentEventListener * Revert "improve dirty checking of new entity instances" in favour of apache/grails-data-mapping#1265 This reverts commit c8b089d.
1 parent 1373930 commit 42fac44

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/dirty/GrailsEntityDirtinessStrategy.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class GrailsEntityDirtinessStrategy implements CustomEntityDirtinessStrategy {
5353

5454
@Override
5555
boolean isDirty(Object entity, EntityPersister persister, Session session) {
56-
!session.contains(entity) || !cast(entity).listDirtyPropertyNames().isEmpty() || DirtyCheckingSupport.areEmbeddedDirty(GormEnhancer.findEntity(Hibernate.getClass(entity)), entity)
56+
!session.contains(entity) || cast(entity).hasChanged() || DirtyCheckingSupport.areEmbeddedDirty(GormEnhancer.findEntity(Hibernate.getClass(entity)), entity)
5757
}
5858

5959
@Override

grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventTriggeringInterceptor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public void setEventPublisher(ConfigurableApplicationEventPublisher eventPublish
122122
public void onSaveOrUpdate(SaveOrUpdateEvent hibernateEvent) throws HibernateException {
123123
Object entity = getEntity(hibernateEvent);
124124
if(entity != null && proxyHandler.isInitialized(entity)) {
125+
activateDirtyChecking(entity);
125126
org.grails.datastore.mapping.engine.event.SaveOrUpdateEvent grailsEvent = new org.grails.datastore.mapping.engine.event.SaveOrUpdateEvent(
126127
this.datastore, entity);
127128
publishEvent(hibernateEvent, grailsEvent);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package grails.gorm.tests.dirtychecking
2+
3+
import grails.gorm.transactions.Rollback
4+
import org.grails.datastore.gorm.events.ConfigurableApplicationEventPublisher
5+
import org.grails.datastore.mapping.core.Datastore
6+
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
7+
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
8+
import org.grails.datastore.mapping.engine.event.PreInsertEvent
9+
import org.grails.datastore.mapping.engine.event.PreUpdateEvent
10+
import org.grails.orm.hibernate.HibernateDatastore
11+
import org.springframework.context.ApplicationEvent
12+
import org.springframework.context.ApplicationEventPublisher
13+
import org.springframework.context.ConfigurableApplicationContext
14+
import org.springframework.transaction.PlatformTransactionManager
15+
import spock.lang.AutoCleanup
16+
import spock.lang.Shared
17+
import spock.lang.Specification
18+
import spock.util.concurrent.PollingConditions
19+
20+
class HibernateUpdateFromListenerSpec extends Specification {
21+
22+
@Shared
23+
@AutoCleanup
24+
HibernateDatastore datastore = new HibernateDatastore(Person)
25+
@Shared PlatformTransactionManager transactionManager = datastore.transactionManager
26+
27+
PersonSaveOrUpdatePersistentEventListener listener
28+
29+
void setup() {
30+
listener = new PersonSaveOrUpdatePersistentEventListener(datastore)
31+
ApplicationEventPublisher publisher = datastore.applicationEventPublisher
32+
if (publisher instanceof ConfigurableApplicationEventPublisher) {
33+
((ConfigurableApplicationEventPublisher) publisher).addApplicationListener(listener)
34+
} else if (publisher instanceof ConfigurableApplicationContext) {
35+
((ConfigurableApplicationContext) publisher).addApplicationListener(listener)
36+
}
37+
}
38+
39+
@Rollback
40+
void "test the changes made from the listener are saved"() {
41+
when:
42+
Person danny = new Person(name: "Danny", occupation: "manager").save()
43+
44+
then:
45+
new PollingConditions().eventually {listener.isExecuted && Person.count()}
46+
47+
when:
48+
datastore.currentSession.flush()
49+
datastore.currentSession.clear()
50+
danny = Person.get(danny.id)
51+
52+
then:
53+
danny.occupation
54+
danny.occupation.endsWith("listener")
55+
}
56+
57+
static class PersonSaveOrUpdatePersistentEventListener extends AbstractPersistenceEventListener {
58+
59+
boolean isExecuted
60+
61+
protected PersonSaveOrUpdatePersistentEventListener(Datastore datastore) {
62+
super(datastore)
63+
}
64+
65+
@Override
66+
protected void onPersistenceEvent(AbstractPersistenceEvent event) {
67+
if (event.entityObject instanceof Person) {
68+
Person person = (Person) event.entityObject
69+
person.occupation = person.occupation + " listener"
70+
}
71+
isExecuted = true
72+
}
73+
74+
@Override
75+
boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
76+
return eventType == PreUpdateEvent || eventType == PreInsertEvent
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)