This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 8.0.x-hibernate7 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 9bc8623f6c119c9031b077c5b7b156e8e4ac24d6 Author: Walter B Duque de Estrada <[email protected]> AuthorDate: Wed Jan 14 14:03:38 2026 -0600 Fix event handling fall-through in HibernateEventListener and add unit tests - Added missing break statements in HibernateEventListener.onPersistenceEvent switch for Merge and Persist event types. - Fixed a typo in Session.merge default implementation exception message. - Changed onMergeEvent and onPersistEvent visibility to protected to allow testing via subclassing. - Added HibernateEventListenerSpec to verify correct event dispatching. --- .../event/listener/HibernateEventListener.java | 6 +- .../listener/HibernateEventListenerSpec.groovy | 81 ++++++++++++++++++++++ .../org/grails/datastore/mapping/core/Session.java | 2 +- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListener.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListener.java index ca782596a9..1c50049c29 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListener.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListener.java @@ -88,8 +88,10 @@ public class HibernateEventListener extends AbstractHibernateEventListener { break; case Merge: onMergeEvent((MergeEvent)event.getNativeEvent()); + break; case Persist: onPersistEvent((PersistEvent)event.getNativeEvent()); + break; case Validation: onValidate((ValidationEvent)event); break; @@ -98,7 +100,7 @@ public class HibernateEventListener extends AbstractHibernateEventListener { } } - private void onPersistEvent(PersistEvent event) { + protected void onPersistEvent(PersistEvent event) { Object entity =event.getObject(); if(entity != null) { ClosureEventListener eventListener; @@ -110,7 +112,7 @@ public class HibernateEventListener extends AbstractHibernateEventListener { } } - private void onMergeEvent(MergeEvent event) { + protected void onMergeEvent(MergeEvent event) { Object entity = Optional.ofNullable(event.getOriginal()).orElse(event.getEntity()); if(entity != null) { ClosureEventListener eventListener; diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListenerSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListenerSpec.groovy new file mode 100644 index 0000000000..63cd62b491 --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/event/listener/HibernateEventListenerSpec.groovy @@ -0,0 +1,81 @@ +package org.grails.orm.hibernate.event.listener + +import grails.gorm.specs.HibernateGormDatastoreSpec +import org.grails.datastore.mapping.engine.event.MergeEvent as GormMergeEvent +import org.grails.datastore.mapping.engine.event.PersistEvent as GormPersistEvent +import org.hibernate.event.spi.MergeEvent as HibernateMergeEvent +import org.hibernate.event.spi.PersistEvent as HibernatePersistEvent +import org.hibernate.event.spi.EventSource + +class HibernateEventListenerSpec extends HibernateGormDatastoreSpec { + + class RecordingHibernateEventListener extends HibernateEventListener { + boolean onMergeEventCalled = false + boolean onPersistEventCalled = false + HibernateMergeEvent lastMergeEvent + HibernatePersistEvent lastPersistEvent + + RecordingHibernateEventListener(org.grails.orm.hibernate.AbstractHibernateDatastore datastore) { + super(datastore) + } + + @Override + protected void onMergeEvent(HibernateMergeEvent event) { + onMergeEventCalled = true + lastMergeEvent = event + } + + @Override + protected void onPersistEvent(HibernatePersistEvent event) { + onPersistEventCalled = true + lastPersistEvent = event + } + + @Override + protected boolean isValidSource(org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent event) { + return true + } + } + + void "test onPersistenceEvent handles Merge event without fall-through"() { + given: + def datastore = getDatastore() + def listener = new RecordingHibernateEventListener(datastore) + def entity = new Object() + def hibernateSession = Mock(EventSource) + + and: "a GORM Merge event wrapping a Hibernate Merge event" + def hibernateMergeEvent = new HibernateMergeEvent("Foo", entity, hibernateSession) + def gormMergeEvent = new GormMergeEvent(datastore, entity) + gormMergeEvent.setNativeEvent(hibernateMergeEvent) + + when: "Merge event is published" + listener.onApplicationEvent(gormMergeEvent) + + then: "Only onMergeEvent is called" + listener.onMergeEventCalled + listener.lastMergeEvent == hibernateMergeEvent + !listener.onPersistEventCalled + } + + void "test onPersistenceEvent handles Persist event without fall-through"() { + given: + def datastore = getDatastore() + def listener = new RecordingHibernateEventListener(datastore) + def entity = new Object() + def hibernateSession = Mock(EventSource) + + and: "a GORM Persist event wrapping a Hibernate Persist event" + def hibernatePersistEvent = new HibernatePersistEvent("Foo", entity, hibernateSession) + def gormPersistEvent = new GormPersistEvent(datastore, entity) + gormPersistEvent.setNativeEvent(hibernatePersistEvent) + + when: "Persist event is published" + listener.onApplicationEvent(gormPersistEvent) + + then: "Only onPersistEvent is called" + listener.onPersistEventCalled + listener.lastPersistEvent == hibernatePersistEvent + !listener.onMergeEventCalled + } +} \ No newline at end of file diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/Session.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/Session.java index 05fd63bee0..f4a4f232e7 100644 --- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/Session.java +++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/Session.java @@ -336,6 +336,6 @@ public interface Session extends QueryCreator { * @return Object */ default Object merge(Object d){ - throw new org.grails.datastore.mapping.core.MethodNotImplementedException("merge(Object) is not implemented for this IHibernateTemplate"); + throw new org.grails.datastore.mapping.core.MethodNotImplementedException("merge(Object) is not implemented for this Session"); } }
