Skip to content
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 @@ -4,6 +4,7 @@
*/
package org.hibernate.event.internal;

import org.hibernate.LockMode;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
import org.hibernate.engine.spi.EntityEntry;
Expand Down Expand Up @@ -290,6 +291,16 @@ public void completeEntityDeleteEvent(

}

@Override
public HibernateMonitoringEvent beginEntityLockEvent() {
return null;
}

@Override
public void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session) {

}

@Override
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package org.hibernate.event.spi;

import org.hibernate.Incubating;
import org.hibernate.LockMode;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
import org.hibernate.engine.spi.EntityEntry;
Expand All @@ -14,11 +15,20 @@
import org.hibernate.service.JavaServiceLoadable;

/**
* Defines the contract for monitoring low-level events
* involving interactions between the {@linkplain org.hibernate.Session}
* and the database or second-level cache.
* Defines a contract for reporting and monitoring low-level events
* involving interactions between the {@linkplain org.hibernate.Session
* session} and the database or second-level cache.
* <p>
* For example, this interface is implemented by Hibernate JFR to report
* events to Java Flight Recorder.
* <p>
* Note that event reporting is different to aggregate <em>metrics</em>,
* which Hibernate exposes via the {@link org.hibernate.stat.Statistics}
* interface.
*
* @apiNote This an incubating API, subject to change.
*
* @since 6.4
*/
@JavaServiceLoadable
@Incubating
Expand Down Expand Up @@ -173,6 +183,10 @@ void completePrePartialFlush(

void completeEntityDeleteEvent(HibernateMonitoringEvent event, Object id, String entityName, boolean success, SharedSessionContractImplementor session);

HibernateMonitoringEvent beginEntityLockEvent();

void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session);

HibernateMonitoringEvent beginCollectionRecreateEvent();

void completeCollectionRecreateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.event.spi.EventManager;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.HibernateMonitoringEvent;
import org.hibernate.loader.LoaderLogging;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
Expand Down Expand Up @@ -107,7 +109,17 @@ public static void upgradeLock(Object object, EntityEntry entry, LockOptions loc
}
else {
if ( entry.isExistsInDatabase() ) {
persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, session );
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent entityLockEvent = eventManager.beginEntityLockEvent();
boolean success = false;
try {
persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, session );
success = true;
}
finally {
eventManager.completeEntityLockEvent( entityLockEvent, entry.getId(),
persister.getEntityName(), lockOptions.getLockMode(), success, session );
}
}
else {
session.forceFlush( entry );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.LockMode;
import org.hibernate.event.spi.HibernateMonitoringEvent;
import org.hibernate.internal.build.AllowNonPortable;

@Name(EntityLockEvent.NAME)
@Label("Entity Delete")
@Category("Hibernate ORM")
@Description("Entity Delete")
@StackTrace
@AllowNonPortable
public class EntityLockEvent extends Event implements HibernateMonitoringEvent {
public static final String NAME = "org.hibernate.orm.EntityDeleteEvent";

@Label("Session Identifier")
public String sessionIdentifier;

@Label("Entity Identifier")
public String id;

@Label("Entity Name")
public String entityName;

@Label("Lock Mode")
public LockMode lockMode;

@Label("Success")
public boolean success;

@Override
public String toString() {
return NAME;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
package org.hibernate.event.jfr.internal;

import org.hibernate.LockMode;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
import org.hibernate.engine.spi.EntityEntry;
Expand Down Expand Up @@ -45,6 +46,7 @@ public class JfrEventManager implements EventManager {
private static final EventType entityUpdateEventType = EventType.getEventType( EntityUpdateEvent.class );
private static final EventType entityUpsertEventType = EventType.getEventType( EntityUpsertEvent.class );
private static final EventType entityDeleteEventType = EventType.getEventType( EntityDeleteEvent.class );
private static final EventType entityLockEventType = EventType.getEventType( EntityLockEvent.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 );
Expand Down Expand Up @@ -656,6 +658,34 @@ public void completeEntityDeleteEvent(
}
}

@Override
public HibernateMonitoringEvent beginEntityLockEvent() {
if ( entityLockEventType.isEnabled() ) {
final EntityLockEvent event = new EntityLockEvent();
event.begin();
return event;
}
else {
return null;
}
}

@Override
public void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session) {
if ( event != null ) {
final EntityLockEvent entityLockEvent = (EntityLockEvent) event;
entityLockEvent.end();
if ( entityLockEvent.shouldCommit() ) {
entityLockEvent.sessionIdentifier = getSessionIdentifier( session );
entityLockEvent.entityName = entityName;
entityLockEvent.id = Objects.toString(id);
entityLockEvent.lockMode = lockMode;
entityLockEvent.success = success;
entityLockEvent.commit();
}
}
}

@Override
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
if ( collectionRecreateEventType.isEnabled() ) {
Expand Down
Loading