diff --git a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index b4725a1968b0..04274d1aa281 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java @@ -41,12 +41,6 @@ import org.hibernate.event.monitor.spi.EventMonitor; import org.hibernate.event.monitor.spi.DiagnosticEvent; import org.hibernate.event.service.spi.EventListenerGroups; -import org.hibernate.event.spi.PostCollectionRecreateEvent; -import org.hibernate.event.spi.PostCollectionRecreateEventListener; -import org.hibernate.event.spi.PostCollectionRemoveEvent; -import org.hibernate.event.spi.PostCollectionRemoveEventListener; -import org.hibernate.event.spi.PostCollectionUpdateEvent; -import org.hibernate.event.spi.PostCollectionUpdateEventListener; import org.hibernate.event.spi.PostDeleteEvent; import org.hibernate.event.spi.PostDeleteEventListener; import org.hibernate.event.spi.PostInsertEvent; @@ -55,12 +49,6 @@ import org.hibernate.event.spi.PostUpdateEventListener; import org.hibernate.event.spi.PostUpsertEvent; import org.hibernate.event.spi.PostUpsertEventListener; -import org.hibernate.event.spi.PreCollectionRecreateEvent; -import org.hibernate.event.spi.PreCollectionRecreateEventListener; -import org.hibernate.event.spi.PreCollectionRemoveEvent; -import org.hibernate.event.spi.PreCollectionRemoveEventListener; -import org.hibernate.event.spi.PreCollectionUpdateEvent; -import org.hibernate.event.spi.PreCollectionUpdateEventListener; import org.hibernate.event.spi.PreDeleteEvent; import org.hibernate.event.spi.PreDeleteEventListener; import org.hibernate.event.spi.PreInsertEvent; @@ -634,46 +622,49 @@ protected void firePostDelete(Object entity, Object id, EntityPersister persiste PostDeleteEventListener::onPostDelete ); } + // Note: the pre/post collection events have been disabled for stateless sessions + // as they were not actually useful (see https://hibernate.atlassian.net/browse/HHH-19523) + // Hibernate Reactive may need to call this protected void firePreRecreate(PersistentCollection collection, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_PRE_COLLECTION_RECREATE.fireLazyEventOnEachListener( - () -> new PreCollectionRecreateEvent( persister, collection, null ), - PreCollectionRecreateEventListener::onPreRecreateCollection ); +// eventListenerGroups.eventListenerGroup_PRE_COLLECTION_RECREATE.fireLazyEventOnEachListener( +// () -> new PreCollectionRecreateEvent( persister, collection, null ), +// PreCollectionRecreateEventListener::onPreRecreateCollection ); } // Hibernate Reactive may need to call this protected void firePreUpdate(PersistentCollection collection, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_PRE_COLLECTION_UPDATE.fireLazyEventOnEachListener( - () -> new PreCollectionUpdateEvent( persister, collection, null ), - PreCollectionUpdateEventListener::onPreUpdateCollection ); +// eventListenerGroups.eventListenerGroup_PRE_COLLECTION_UPDATE.fireLazyEventOnEachListener( +// () -> new PreCollectionUpdateEvent( persister, collection, null ), +// PreCollectionUpdateEventListener::onPreUpdateCollection ); } // Hibernate Reactive may need to call this protected void firePreRemove(PersistentCollection collection, Object owner, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_PRE_COLLECTION_REMOVE.fireLazyEventOnEachListener( - () -> new PreCollectionRemoveEvent( persister, collection, null, owner ), - PreCollectionRemoveEventListener::onPreRemoveCollection ); +// eventListenerGroups.eventListenerGroup_PRE_COLLECTION_REMOVE.fireLazyEventOnEachListener( +// () -> new PreCollectionRemoveEvent( persister, collection, null, owner ), +// PreCollectionRemoveEventListener::onPreRemoveCollection ); } // Hibernate Reactive may need to call this protected void firePostRecreate(PersistentCollection collection, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_POST_COLLECTION_RECREATE.fireLazyEventOnEachListener( - () -> new PostCollectionRecreateEvent( persister, collection, null ), - PostCollectionRecreateEventListener::onPostRecreateCollection ); +// eventListenerGroups.eventListenerGroup_POST_COLLECTION_RECREATE.fireLazyEventOnEachListener( +// () -> new PostCollectionRecreateEvent( persister, collection, null ), +// PostCollectionRecreateEventListener::onPostRecreateCollection ); } // Hibernate Reactive may need to call this protected void firePostUpdate(PersistentCollection collection, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_POST_COLLECTION_UPDATE.fireLazyEventOnEachListener( - () -> new PostCollectionUpdateEvent( persister, collection, null ), - PostCollectionUpdateEventListener::onPostUpdateCollection ); +// eventListenerGroups.eventListenerGroup_POST_COLLECTION_UPDATE.fireLazyEventOnEachListener( +// () -> new PostCollectionUpdateEvent( persister, collection, null ), +// PostCollectionUpdateEventListener::onPostUpdateCollection ); } // Hibernate Reactive may need to call this protected void firePostRemove(PersistentCollection collection, Object owner, CollectionPersister persister) { - eventListenerGroups.eventListenerGroup_POST_COLLECTION_REMOVE.fireLazyEventOnEachListener( - () -> new PostCollectionRemoveEvent( persister, collection, null, owner ), - PostCollectionRemoveEventListener::onPostRemoveCollection ); +// eventListenerGroups.eventListenerGroup_POST_COLLECTION_REMOVE.fireLazyEventOnEachListener( +// () -> new PostCollectionRemoveEvent( persister, collection, null, owner ), +// PostCollectionRemoveEventListener::onPostRemoveCollection ); } // collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/CollectionListenerInStatelessSessionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/CollectionListenerInStatelessSessionTest.java new file mode 100644 index 000000000000..bcefa3a83c22 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/CollectionListenerInStatelessSessionTest.java @@ -0,0 +1,108 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.stateless.events; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; +import org.hibernate.event.spi.PostCollectionRecreateEvent; +import org.hibernate.event.spi.PostCollectionRecreateEventListener; +import org.hibernate.event.spi.PostCollectionRemoveEvent; +import org.hibernate.event.spi.PostCollectionRemoveEventListener; +import org.hibernate.event.spi.PreCollectionRecreateEvent; +import org.hibernate.event.spi.PreCollectionRecreateEventListener; +import org.hibernate.event.spi.PreCollectionRemoveEvent; +import org.hibernate.event.spi.PreCollectionRemoveEventListener; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DomainModel(annotatedClasses = {EntityA.class, EntityB.class}) +@SessionFactory +class CollectionListenerInStatelessSessionTest { + + @Test + void statelessInsert(SessionFactoryScope scope) { + EventListenerRegistry registry = + scope.getSessionFactory().unwrap(SessionFactoryImplementor.class) + .getServiceRegistry().getService(EventListenerRegistry.class); + var preRecreate = new MyPreCollectionRecreateEventListener(); + var preRemove = new MyPreCollectionRemoveEventListener(); + var postRecreate = new MyPostCollectionRecreateEventListener(); + var postRemove = new MyPostCollectionRemoveEventListener(); + registry.getEventListenerGroup(EventType.PRE_COLLECTION_RECREATE) + .appendListener( preRecreate ); + registry.getEventListenerGroup(EventType.PRE_COLLECTION_REMOVE) + .appendListener( preRemove ); + registry.getEventListenerGroup(EventType.POST_COLLECTION_RECREATE) + .appendListener( postRecreate ); + registry.getEventListenerGroup(EventType.POST_COLLECTION_REMOVE) + .appendListener( postRemove ); + + scope.inStatelessTransaction(statelessSession -> { + EntityA a = new EntityA(); + EntityB b = new EntityB(); + a.children.add(b); + statelessSession.insert( b ); + statelessSession.insert( a ); + statelessSession.delete( a ); + statelessSession.delete( b ); + }); + + // Note : in 7.0, the StatelessSession does not trigger collection events + assertEquals(0, preRecreate.called); + assertEquals(0, preRemove.called); + assertEquals(0, postRecreate.called); + assertEquals(0, postRemove.called); + } + +} + +class MyPreCollectionRecreateEventListener implements PreCollectionRecreateEventListener { + + int called = 0; + + @Override + public void onPreRecreateCollection(PreCollectionRecreateEvent event) { + called++; + } + +} + +class MyPreCollectionRemoveEventListener implements PreCollectionRemoveEventListener { + + int called = 0; + + @Override + public void onPreRemoveCollection(PreCollectionRemoveEvent event) { + called++; + } + +} + +class MyPostCollectionRecreateEventListener implements PostCollectionRecreateEventListener { + + int called = 0; + + @Override + public void onPostRecreateCollection(PostCollectionRecreateEvent event) { + called++; + } + +} + +class MyPostCollectionRemoveEventListener implements PostCollectionRemoveEventListener { + + int called = 0; + + @Override + public void onPostRemoveCollection(PostCollectionRemoveEvent event) { + called++; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityA.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityA.java new file mode 100644 index 000000000000..183d38fcc9ef --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityA.java @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.stateless.events; + +import java.util.ArrayList; +import java.util.Collection; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +@Entity +@Table(name = "ENTITY_A") +public class EntityA { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "ID") + Integer id; + + @OneToMany + @JoinColumn(name = "ENTITY_A") + Collection children = new ArrayList<>(); + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityB.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityB.java new file mode 100644 index 000000000000..2ec190c13335 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/events/EntityB.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.stateless.events; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "ENTITY_B") +public class EntityB { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "ID") + Integer id; +}