HHH-18942 JFR events for collection recreate/update/remove
This commit is contained in:
parent
ad1a86f570
commit
caed673720
|
@ -7,7 +7,9 @@ package org.hibernate.action.internal;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.EventManager;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.event.spi.PostCollectionRecreateEvent;
|
||||
import org.hibernate.event.spi.PostCollectionRecreateEventListener;
|
||||
import org.hibernate.event.spi.PreCollectionRecreateEvent;
|
||||
|
@ -42,14 +44,26 @@ public final class CollectionRecreateAction extends CollectionAction {
|
|||
final PersistentCollection<?> collection = getCollection();
|
||||
preRecreate();
|
||||
final SharedSessionContractImplementor session = getSession();
|
||||
getPersister().recreate( collection, getKey(), session);
|
||||
final CollectionPersister persister = getPersister();
|
||||
final Object key = getKey();
|
||||
final EventManager eventManager = session.getEventManager();
|
||||
final HibernateMonitoringEvent event = eventManager.beginCollectionRecreateEvent();
|
||||
boolean success = false;
|
||||
try {
|
||||
persister.recreate( collection, key, session );
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
eventManager.completeCollectionRecreateEvent( event, key, persister.getRole(), success, session );
|
||||
}
|
||||
|
||||
session.getPersistenceContextInternal().getCollectionEntry( collection ).afterAction( collection );
|
||||
evict();
|
||||
postRecreate();
|
||||
|
||||
final StatisticsImplementor statistics = session.getFactory().getStatistics();
|
||||
if ( statistics.isStatisticsEnabled() ) {
|
||||
statistics.recreateCollection( getPersister().getRole() );
|
||||
statistics.recreateCollection( persister.getRole() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ import org.hibernate.AssertionFailure;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.EventManager;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.event.spi.PostCollectionRemoveEvent;
|
||||
import org.hibernate.event.spi.PostCollectionRemoveEventListener;
|
||||
import org.hibernate.event.spi.PreCollectionRemoveEvent;
|
||||
|
@ -108,8 +110,20 @@ public final class CollectionRemoveAction extends CollectionAction {
|
|||
// is replaced by null or a different collection
|
||||
// (if the collection is uninitialized, Hibernate has no way of
|
||||
// knowing if the collection is actually empty without querying the db)
|
||||
getPersister().remove( getKey(), session );
|
||||
final CollectionPersister persister = getPersister();
|
||||
final Object key = getKey();
|
||||
final EventManager eventManager = session.getEventManager();
|
||||
final HibernateMonitoringEvent event = eventManager.beginCollectionRemoveEvent();
|
||||
boolean success = false;
|
||||
try {
|
||||
persister.remove( key, session );
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
eventManager.completeCollectionRemoveEvent( event, key, persister.getRole(), success, session );
|
||||
}
|
||||
}
|
||||
|
||||
final PersistentCollection<?> collection = getCollection();
|
||||
if ( collection != null ) {
|
||||
session.getPersistenceContextInternal().getCollectionEntry( collection ).afterAction( collection );
|
||||
|
@ -130,12 +144,7 @@ public final class CollectionRemoveAction extends CollectionAction {
|
|||
}
|
||||
|
||||
private PreCollectionRemoveEvent newPreCollectionRemoveEvent() {
|
||||
return new PreCollectionRemoveEvent(
|
||||
getPersister(),
|
||||
getCollection(),
|
||||
eventSource(),
|
||||
affectedOwner
|
||||
);
|
||||
return new PreCollectionRemoveEvent( getPersister(), getCollection(), eventSource(), affectedOwner );
|
||||
}
|
||||
|
||||
private void postRemove() {
|
||||
|
@ -145,12 +154,7 @@ public final class CollectionRemoveAction extends CollectionAction {
|
|||
}
|
||||
|
||||
private PostCollectionRemoveEvent newPostCollectionRemoveEvent() {
|
||||
return new PostCollectionRemoveEvent(
|
||||
getPersister(),
|
||||
getCollection(),
|
||||
eventSource(),
|
||||
affectedOwner
|
||||
);
|
||||
return new PostCollectionRemoveEvent( getPersister(), getCollection(), eventSource(), affectedOwner );
|
||||
}
|
||||
|
||||
public Object getAffectedOwner() {
|
||||
|
|
|
@ -8,7 +8,9 @@ import org.hibernate.AssertionFailure;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.EventManager;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.event.spi.PostCollectionUpdateEvent;
|
||||
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
|
||||
import org.hibernate.event.spi.PreCollectionUpdateEvent;
|
||||
|
@ -45,7 +47,7 @@ public final class CollectionUpdateAction extends CollectionAction {
|
|||
|
||||
@Override
|
||||
public void execute() throws HibernateException {
|
||||
final Object id = getKey();
|
||||
final Object key = getKey();
|
||||
final SharedSessionContractImplementor session = getSession();
|
||||
final CollectionPersister persister = getPersister();
|
||||
final PersistentCollection<?> collection = getCollection();
|
||||
|
@ -54,34 +56,45 @@ public final class CollectionUpdateAction extends CollectionAction {
|
|||
preUpdate();
|
||||
|
||||
if ( !collection.wasInitialized() ) {
|
||||
// If there were queued operations, they would have been processed
|
||||
// and cleared by now.
|
||||
// The collection should still be dirty.
|
||||
// If there were queued operations, they would have
|
||||
// been processed and cleared by now.
|
||||
if ( !collection.isDirty() ) {
|
||||
// The collection should still be dirty.
|
||||
throw new AssertionFailure( "collection is not dirty" );
|
||||
}
|
||||
//do nothing - we only need to notify the cache...
|
||||
}
|
||||
else if ( !affectedByFilters && collection.empty() ) {
|
||||
if ( !emptySnapshot ) {
|
||||
persister.remove( id, session );
|
||||
}
|
||||
}
|
||||
else if ( collection.needsRecreate( persister ) ) {
|
||||
if ( affectedByFilters ) {
|
||||
throw new HibernateException( "cannot recreate collection while filter is enabled: "
|
||||
+ collectionInfoString( persister, collection, id, session )
|
||||
);
|
||||
}
|
||||
if ( !emptySnapshot ) {
|
||||
persister.remove( id, session );
|
||||
}
|
||||
persister.recreate( collection, id, session );
|
||||
// Do nothing - we only need to notify the cache
|
||||
}
|
||||
else {
|
||||
persister.deleteRows( collection, id, session );
|
||||
persister.updateRows( collection, id, session );
|
||||
persister.insertRows( collection, id, session );
|
||||
final EventManager eventManager = session.getEventManager();
|
||||
final HibernateMonitoringEvent event = eventManager.beginCollectionUpdateEvent();
|
||||
boolean success = false;
|
||||
try {
|
||||
if ( !affectedByFilters && collection.empty() ) {
|
||||
if ( !emptySnapshot ) {
|
||||
persister.remove( key, session );
|
||||
}
|
||||
//TODO: else we really shouldn't have sent an update event to JFR
|
||||
}
|
||||
else if ( collection.needsRecreate( persister ) ) {
|
||||
if ( affectedByFilters ) {
|
||||
throw new HibernateException( "cannot recreate collection while filter is enabled: "
|
||||
+ collectionInfoString( persister, collection, key, session ) );
|
||||
}
|
||||
if ( !emptySnapshot ) {
|
||||
persister.remove( key, session );
|
||||
}
|
||||
persister.recreate( collection, key, session );
|
||||
}
|
||||
else {
|
||||
persister.deleteRows( collection, key, session );
|
||||
persister.updateRows( collection, key, session );
|
||||
persister.insertRows( collection, key, session );
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
eventManager.completeCollectionUpdateEvent( event, key, persister.getRole(), success, session );
|
||||
}
|
||||
}
|
||||
|
||||
session.getPersistenceContextInternal().getCollectionEntry( collection ).afterAction( collection );
|
||||
|
@ -101,11 +114,7 @@ public final class CollectionUpdateAction extends CollectionAction {
|
|||
}
|
||||
|
||||
private PreCollectionUpdateEvent newPreCollectionUpdateEvent() {
|
||||
return new PreCollectionUpdateEvent(
|
||||
getPersister(),
|
||||
getCollection(),
|
||||
eventSource()
|
||||
);
|
||||
return new PreCollectionUpdateEvent( getPersister(), getCollection(), eventSource() );
|
||||
}
|
||||
|
||||
private void postUpdate() {
|
||||
|
@ -115,11 +124,7 @@ public final class CollectionUpdateAction extends CollectionAction {
|
|||
}
|
||||
|
||||
private PostCollectionUpdateEvent newPostCollectionUpdateEvent() {
|
||||
return new PostCollectionUpdateEvent(
|
||||
getPersister(),
|
||||
getCollection(),
|
||||
eventSource()
|
||||
);
|
||||
return new PostCollectionUpdateEvent( getPersister(), getCollection(), eventSource() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ import org.hibernate.event.spi.FlushEvent;
|
|||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* An {@link EventManager} that ignores all events.
|
||||
*/
|
||||
public final class EmptyEventManager implements EventManager {
|
||||
|
||||
@Override
|
||||
|
@ -276,4 +279,34 @@ public final class EmptyEventManager implements EventManager {
|
|||
SharedSessionContractImplementor session) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionRecreateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionUpdateEvent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionUpdateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionRemoveEvent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionRemoveEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,18 @@ public interface EventManager {
|
|||
|
||||
void completeEntityDeleteEvent(HibernateMonitoringEvent event, Object id, String entityName, boolean success, SharedSessionContractImplementor session);
|
||||
|
||||
HibernateMonitoringEvent beginCollectionRecreateEvent();
|
||||
|
||||
void completeCollectionRecreateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session);
|
||||
|
||||
HibernateMonitoringEvent beginCollectionUpdateEvent();
|
||||
|
||||
void completeCollectionUpdateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session);
|
||||
|
||||
HibernateMonitoringEvent beginCollectionRemoveEvent();
|
||||
|
||||
void completeCollectionRemoveEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session);
|
||||
|
||||
enum CacheActionDescription {
|
||||
ENTITY_INSERT( "Entity Insert" ),
|
||||
ENTITY_AFTER_INSERT( "Entity After Insert" ),
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
* Copyright Red Hat Inc. and Hibernate Authors
|
||||
*/
|
||||
package org.hibernate.event.jfr.internal;
|
||||
|
||||
import jdk.jfr.Category;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.StackTrace;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.internal.build.AllowNonPortable;
|
||||
|
||||
@Name(CollectionRecreateEvent.NAME)
|
||||
@Label("Collection Recreate")
|
||||
@Category("Hibernate ORM")
|
||||
@Description("Collection Recreate")
|
||||
@StackTrace
|
||||
@AllowNonPortable
|
||||
public class CollectionRecreateEvent extends Event implements HibernateMonitoringEvent {
|
||||
public static final String NAME = "org.hibernate.orm.CollectionRecreateEvent";
|
||||
|
||||
@Label("Session Identifier")
|
||||
public String sessionIdentifier;
|
||||
|
||||
@Label("Entity Identifier")
|
||||
public String id;
|
||||
|
||||
@Label("Collection Role")
|
||||
public String role;
|
||||
|
||||
@Label("Success")
|
||||
public boolean success;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
* Copyright Red Hat Inc. and Hibernate Authors
|
||||
*/
|
||||
package org.hibernate.event.jfr.internal;
|
||||
|
||||
import jdk.jfr.Category;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.StackTrace;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.internal.build.AllowNonPortable;
|
||||
|
||||
@Name(CollectionRemoveEvent.NAME)
|
||||
@Label("Collection Remove")
|
||||
@Category("Hibernate ORM")
|
||||
@Description("Collection Remove")
|
||||
@StackTrace
|
||||
@AllowNonPortable
|
||||
public class CollectionRemoveEvent extends Event implements HibernateMonitoringEvent {
|
||||
public static final String NAME = "org.hibernate.orm.CollectionRemoveEvent";
|
||||
|
||||
@Label("Session Identifier")
|
||||
public String sessionIdentifier;
|
||||
|
||||
@Label("Entity Identifier")
|
||||
public String id;
|
||||
|
||||
@Label("Collection Role")
|
||||
public String role;
|
||||
|
||||
@Label("Success")
|
||||
public boolean success;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
* Copyright Red Hat Inc. and Hibernate Authors
|
||||
*/
|
||||
package org.hibernate.event.jfr.internal;
|
||||
|
||||
import jdk.jfr.Category;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.StackTrace;
|
||||
import org.hibernate.event.spi.HibernateMonitoringEvent;
|
||||
import org.hibernate.internal.build.AllowNonPortable;
|
||||
|
||||
@Name(CollectionUpdateEvent.NAME)
|
||||
@Label("Collection Update")
|
||||
@Category("Hibernate ORM")
|
||||
@Description("Collection Update")
|
||||
@StackTrace
|
||||
@AllowNonPortable
|
||||
public class CollectionUpdateEvent extends Event implements HibernateMonitoringEvent {
|
||||
public static final String NAME = "org.hibernate.orm.CollectionUpdateEvent";
|
||||
|
||||
@Label("Session Identifier")
|
||||
public String sessionIdentifier;
|
||||
|
||||
@Label("Entity Identifier")
|
||||
public String id;
|
||||
|
||||
@Label("Collection Role")
|
||||
public String role;
|
||||
|
||||
@Label("Success")
|
||||
public boolean success;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,9 @@ public class JfrEventManager implements EventManager {
|
|||
private static final EventType entityInsertEventType = EventType.getEventType( EntityInsertEvent.class );
|
||||
private static final EventType entityUpdateEventType = EventType.getEventType( EntityUpdateEvent.class );
|
||||
private static final EventType entityDeleteEventType = EventType.getEventType( EntityDeleteEvent.class );
|
||||
private static final EventType collectionRecreateEventType = EventType.getEventType( CollectionRecreateEvent.class );
|
||||
private static final EventType collectionUpdateEventType = EventType.getEventType( CollectionUpdateEvent.class );
|
||||
private static final EventType collectionRemoveEventType = EventType.getEventType( CollectionRemoveEvent.class );
|
||||
|
||||
@Override
|
||||
public SessionOpenEvent beginSessionOpenEvent() {
|
||||
|
@ -621,6 +624,99 @@ public class JfrEventManager implements EventManager {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
|
||||
if ( collectionRecreateEventType.isEnabled() ) {
|
||||
final CollectionRecreateEvent event = new CollectionRecreateEvent();
|
||||
event.begin();
|
||||
return event;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionRecreateEvent(
|
||||
HibernateMonitoringEvent event,
|
||||
Object id, String role,
|
||||
boolean success,
|
||||
SharedSessionContractImplementor session) {
|
||||
if ( event != null ) {
|
||||
final CollectionRecreateEvent entityInsertEvent = (CollectionRecreateEvent) event;
|
||||
entityInsertEvent.end();
|
||||
if ( entityInsertEvent.shouldCommit() ) {
|
||||
entityInsertEvent.sessionIdentifier = getSessionIdentifier( session );
|
||||
entityInsertEvent.role = role;
|
||||
entityInsertEvent.id = Objects.toString(id);
|
||||
entityInsertEvent.success = success;
|
||||
entityInsertEvent.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionUpdateEvent() {
|
||||
if ( collectionUpdateEventType.isEnabled() ) {
|
||||
final CollectionUpdateEvent event = new CollectionUpdateEvent();
|
||||
event.begin();
|
||||
return event;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionUpdateEvent(
|
||||
HibernateMonitoringEvent event,
|
||||
Object id, String role,
|
||||
boolean success,
|
||||
SharedSessionContractImplementor session) {
|
||||
if ( event != null ) {
|
||||
final CollectionUpdateEvent entityUpdateEvent = (CollectionUpdateEvent) event;
|
||||
entityUpdateEvent.end();
|
||||
if ( entityUpdateEvent.shouldCommit() ) {
|
||||
entityUpdateEvent.sessionIdentifier = getSessionIdentifier( session );
|
||||
entityUpdateEvent.role = role;
|
||||
entityUpdateEvent.id = Objects.toString(id);
|
||||
entityUpdateEvent.success = success;
|
||||
entityUpdateEvent.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HibernateMonitoringEvent beginCollectionRemoveEvent() {
|
||||
if ( collectionRemoveEventType.isEnabled() ) {
|
||||
final CollectionRemoveEvent event = new CollectionRemoveEvent();
|
||||
event.begin();
|
||||
return event;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeCollectionRemoveEvent(
|
||||
HibernateMonitoringEvent event,
|
||||
Object id, String role,
|
||||
boolean success,
|
||||
SharedSessionContractImplementor session) {
|
||||
if ( event != null ) {
|
||||
final CollectionRemoveEvent entityDeleteEvent = (CollectionRemoveEvent) event;
|
||||
entityDeleteEvent.end();
|
||||
if ( entityDeleteEvent.shouldCommit() ) {
|
||||
entityDeleteEvent.sessionIdentifier = getSessionIdentifier( session );
|
||||
entityDeleteEvent.role = role;
|
||||
entityDeleteEvent.id = Objects.toString(id);
|
||||
entityDeleteEvent.success = success;
|
||||
entityDeleteEvent.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getSessionIdentifier(SharedSessionContractImplementor session) {
|
||||
if ( session == null ) {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue