Skip to content

HHH-19523 correctly initialize Pre/PostCollectionXxxxEvents from StatelessSession #10422

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

Merged
merged 2 commits into from
Jun 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ public abstract class AbstractCollectionEvent extends AbstractEvent {
private final String affectedOwnerEntityName;

/**
* Constructs an AbstractCollectionEvent object.
* @param collection - the collection
* Constructs an instance for a stateful session.
* @param collection - the collection
* @param source - the Session source
* @param affectedOwner - the owner that is affected by this event;
* can be null if unavailable
* can be null if unavailable
* @param affectedOwnerId - the ID for the owner that is affected
* by this event; can be null if unavailable
* by this event; can be null if unavailable
*/
public AbstractCollectionEvent(
CollectionPersister collectionPersister,
Expand All @@ -44,6 +44,27 @@ public AbstractCollectionEvent(
getAffectedOwnerEntityName( collectionPersister, affectedOwner, source );
}

/**
* Constructs an instance for a stateless session.
* @param collection - the collection
* @param entityName - the name of the owning entity
* @param affectedOwner - the owner that is affected by this event;
* can be null if unavailable
* @param affectedOwnerId - the ID for the owner that is affected
* by this event; can be null if unavailable
*/
public AbstractCollectionEvent(
PersistentCollection<?> collection,
String entityName,
Object affectedOwner,
Object affectedOwnerId) {
super( null );
this.collection = collection;
this.affectedOwner = affectedOwner;
this.affectedOwnerId = affectedOwnerId;
this.affectedOwnerEntityName = entityName;
}

protected static CollectionPersister getLoadedCollectionPersister( PersistentCollection<?> collection, EventSource source ) {
CollectionEntry ce = source.getPersistenceContextInternal().getCollectionEntry( collection );
return ce == null ? null : ce.getLoadedPersister();
Expand All @@ -58,7 +79,7 @@ protected static Object getLoadedOwnerIdOrNull(PersistentCollection<?> collectio
}

protected static Object getOwnerIdOrNull(Object owner, EventSource source ) {
EntityEntry ownerEntry = source.getPersistenceContextInternal().getEntry( owner );
final EntityEntry ownerEntry = source.getPersistenceContextInternal().getEntry( owner );
return ownerEntry == null ? null : ownerEntry.getId();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@ public PostCollectionRecreateEvent(
getOwnerIdOrNull( collection.getOwner(), source )
);
}

public PostCollectionRecreateEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ public PostCollectionRemoveEvent(
PersistentCollection<?> collection,
EventSource source,
Object loadedOwner) {
super( collectionPersister, collection, source, loadedOwner, getOwnerIdOrNull( loadedOwner, source ) );
super(
collectionPersister,
collection,
source,
loadedOwner,
getOwnerIdOrNull( loadedOwner, source )
);
}

public PostCollectionRemoveEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ public PostCollectionUpdateEvent(
getLoadedOwnerIdOrNull( collection, source )
);
}


public PostCollectionUpdateEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ public PreCollectionRecreateEvent(
getOwnerIdOrNull( collection.getOwner(), source )
);
}


public PreCollectionRecreateEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ public PreCollectionRemoveEvent(
getOwnerIdOrNull( loadedOwner, source )
);
}

public PreCollectionRemoveEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ public PreCollectionUpdateEvent(
getLoadedOwnerIdOrNull( collection, source )
);
}


public PreCollectionUpdateEvent(
PersistentCollection<?> collection,
Object id,
String entityName,
Object loadedOwner) {
super( collection, entityName, loadedOwner, id );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,25 +275,29 @@ else if ( generator.generatedOnExecution( entity, this ) ) {
}

private void recreateCollections(Object entity, Object id, EntityPersister persister) {
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
firePreRecreate( collection, descriptor );
final EventMonitor eventMonitor = getEventMonitor();
final DiagnosticEvent event = eventMonitor.beginCollectionRecreateEvent();
boolean success = false;
try {
descriptor.recreate( collection, id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRecreateEvent( event, id, descriptor.getRole(), success, this );
}
final StatisticsImplementor statistics = getFactory().getStatistics();
if ( statistics.isStatisticsEnabled() ) {
statistics.recreateCollection( descriptor.getRole() );
}
firePostRecreate( collection, descriptor );
} );
if ( persister.hasOwnedCollections() ) {
final String entityName = persister.getEntityName();
final EventMonitor eventMonitor = getEventMonitor();
final StatisticsImplementor statistics = getFactory().getStatistics();
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
final String role = descriptor.getRole();
firePreRecreate( collection, id, entityName, entity );
final DiagnosticEvent event = eventMonitor.beginCollectionRecreateEvent();
boolean success = false;
try {
descriptor.recreate( collection, id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRecreateEvent( event, id, role, success, this );
}
if ( statistics.isStatisticsEnabled() ) {
statistics.recreateCollection( role );
}
firePostRecreate( collection, id, entityName, entity );
} );
}
}

// deletes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -347,25 +351,29 @@ public void delete(String entityName, Object entity) {
}

private void removeCollections(Object entity, Object id, EntityPersister persister) {
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
firePreRemove( collection, entity, descriptor );
final EventMonitor eventMonitor = getEventMonitor();
final DiagnosticEvent event = eventMonitor.beginCollectionRemoveEvent();
boolean success = false;
try {
descriptor.remove( id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRemoveEvent( event, id, descriptor.getRole(), success, this );
}
firePostRemove( collection, entity, descriptor );
final StatisticsImplementor statistics = getFactory().getStatistics();
if ( statistics.isStatisticsEnabled() ) {
statistics.removeCollection( descriptor.getRole() );
}
} );
if ( persister.hasOwnedCollections() ) {
final String entityName = persister.getEntityName();
final EventMonitor eventMonitor = getEventMonitor();
final StatisticsImplementor statistics = getFactory().getStatistics();
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
final String role = descriptor.getRole();
firePreRemove( collection, id, entityName, entity );
final DiagnosticEvent event = eventMonitor.beginCollectionRemoveEvent();
boolean success = false;
try {
descriptor.remove( id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRemoveEvent( event, id, role, success, this );
}
firePostRemove( collection, id, entityName, entity );
if ( statistics.isStatisticsEnabled() ) {
statistics.removeCollection( role );
}
} );
}
}


Expand Down Expand Up @@ -430,27 +438,31 @@ public void update(String entityName, Object entity) {
}

private void removeAndRecreateCollections(Object entity, Object id, EntityPersister persister) {
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
firePreUpdate( collection, descriptor );
final EventMonitor eventMonitor = getEventMonitor();
final DiagnosticEvent event = eventMonitor.beginCollectionRemoveEvent();
boolean success = false;
try {
// TODO: can we do better here?
descriptor.remove( id, this );
descriptor.recreate( collection, id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRemoveEvent( event, id, descriptor.getRole(), success, this );
}
firePostUpdate( collection, descriptor );
final StatisticsImplementor statistics = getFactory().getStatistics();
if ( statistics.isStatisticsEnabled() ) {
statistics.updateCollection( descriptor.getRole() );
}
} );
if ( persister.hasOwnedCollections() ) {
final String entityName = persister.getEntityName();
final EventMonitor eventMonitor = getEventMonitor();
final StatisticsImplementor statistics = getFactory().getStatistics();
forEachOwnedCollection( entity, id, persister,
(descriptor, collection) -> {
final String role = descriptor.getRole();
firePreUpdate( collection, id, entityName, entity );
final DiagnosticEvent event = eventMonitor.beginCollectionRemoveEvent();
boolean success = false;
try {
// TODO: can we do better here?
descriptor.remove( id, this );
descriptor.recreate( collection, id, this );
success = true;
}
finally {
eventMonitor.completeCollectionRemoveEvent( event, id, role, success, this );
}
firePostUpdate( collection, id, entityName, entity );
if ( statistics.isStatisticsEnabled() ) {
statistics.updateCollection( role );
}
} );
}
}

@Override
Expand Down Expand Up @@ -635,44 +647,44 @@ protected void firePostDelete(Object entity, Object id, EntityPersister persiste
}

// Hibernate Reactive may need to call this
protected void firePreRecreate(PersistentCollection<?> collection, CollectionPersister persister) {
protected void firePreRecreate(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_PRE_COLLECTION_RECREATE.fireLazyEventOnEachListener(
() -> new PreCollectionRecreateEvent( persister, collection, null ),
() -> new PreCollectionRecreateEvent( collection, id, entityName, owner ),
PreCollectionRecreateEventListener::onPreRecreateCollection );
}

// Hibernate Reactive may need to call this
protected void firePreUpdate(PersistentCollection<?> collection, CollectionPersister persister) {
protected void firePreUpdate(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_PRE_COLLECTION_UPDATE.fireLazyEventOnEachListener(
() -> new PreCollectionUpdateEvent( persister, collection, null ),
() -> new PreCollectionUpdateEvent( collection, id, entityName, owner ),
PreCollectionUpdateEventListener::onPreUpdateCollection );
}

// Hibernate Reactive may need to call this
protected void firePreRemove(PersistentCollection<?> collection, Object owner, CollectionPersister persister) {
protected void firePreRemove(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_PRE_COLLECTION_REMOVE.fireLazyEventOnEachListener(
() -> new PreCollectionRemoveEvent( persister, collection, null, owner ),
() -> new PreCollectionRemoveEvent( collection, id, entityName, owner ),
PreCollectionRemoveEventListener::onPreRemoveCollection );
}

// Hibernate Reactive may need to call this
protected void firePostRecreate(PersistentCollection<?> collection, CollectionPersister persister) {
protected void firePostRecreate(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_POST_COLLECTION_RECREATE.fireLazyEventOnEachListener(
() -> new PostCollectionRecreateEvent( persister, collection, null ),
() -> new PostCollectionRecreateEvent( collection, id, entityName, owner ),
PostCollectionRecreateEventListener::onPostRecreateCollection );
}

// Hibernate Reactive may need to call this
protected void firePostUpdate(PersistentCollection<?> collection, CollectionPersister persister) {
protected void firePostUpdate(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_POST_COLLECTION_UPDATE.fireLazyEventOnEachListener(
() -> new PostCollectionUpdateEvent( persister, collection, null ),
() -> new PostCollectionUpdateEvent( collection, id, entityName, owner ),
PostCollectionUpdateEventListener::onPostUpdateCollection );
}

// Hibernate Reactive may need to call this
protected void firePostRemove(PersistentCollection<?> collection, Object owner, CollectionPersister persister) {
protected void firePostRemove(PersistentCollection<?> collection, Object id, String entityName, Object owner) {
eventListenerGroups.eventListenerGroup_POST_COLLECTION_REMOVE.fireLazyEventOnEachListener(
() -> new PostCollectionRemoveEvent( persister, collection, null, owner ),
() -> new PostCollectionRemoveEvent( collection, id, entityName, owner ),
PostCollectionRemoveEventListener::onPostRemoveCollection );
}

Expand Down
Loading
Loading