Skip to content

Commit b1eb194

Browse files
committed
HHH-18942 JFR lock entity event
1 parent 1d3124e commit b1eb194

File tree

5 files changed

+117
-4
lines changed

5 files changed

+117
-4
lines changed

hibernate-core/src/main/java/org/hibernate/event/internal/EmptyEventManager.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.event.internal;
66

7+
import org.hibernate.LockMode;
78
import org.hibernate.cache.spi.Region;
89
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
910
import org.hibernate.engine.spi.EntityEntry;
@@ -290,6 +291,16 @@ public void completeEntityDeleteEvent(
290291

291292
}
292293

294+
@Override
295+
public HibernateMonitoringEvent beginEntityLockEvent() {
296+
return null;
297+
}
298+
299+
@Override
300+
public void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session) {
301+
302+
}
303+
293304
@Override
294305
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
295306
return null;

hibernate-core/src/main/java/org/hibernate/event/spi/EventManager.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.hibernate.event.spi;
66

77
import org.hibernate.Incubating;
8+
import org.hibernate.LockMode;
89
import org.hibernate.cache.spi.Region;
910
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
1011
import org.hibernate.engine.spi.EntityEntry;
@@ -14,11 +15,20 @@
1415
import org.hibernate.service.JavaServiceLoadable;
1516

1617
/**
17-
* Defines the contract for monitoring low-level events
18-
* involving interactions between the {@linkplain org.hibernate.Session}
19-
* and the database or second-level cache.
18+
* Defines a contract for reporting and monitoring low-level events
19+
* involving interactions between the {@linkplain org.hibernate.Session
20+
* session} and the database or second-level cache.
21+
* <p>
22+
* For example, this interface is implemented by Hibernate JFR to report
23+
* events to Java Flight Recorder.
24+
* <p>
25+
* Note that event reporting is different to aggregate <em>metrics</em>,
26+
* which Hibernate exposes via the {@link org.hibernate.stat.Statistics}
27+
* interface.
2028
*
2129
* @apiNote This an incubating API, subject to change.
30+
*
31+
* @since 6.4
2232
*/
2333
@JavaServiceLoadable
2434
@Incubating
@@ -173,6 +183,10 @@ void completePrePartialFlush(
173183

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

186+
HibernateMonitoringEvent beginEntityLockEvent();
187+
188+
void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session);
189+
176190
HibernateMonitoringEvent beginCollectionRecreateEvent();
177191

178192
void completeCollectionRecreateEvent(HibernateMonitoringEvent event, Object id, String role, boolean success, SharedSessionContractImplementor session);

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import org.hibernate.engine.spi.SessionFactoryImplementor;
1919
import org.hibernate.engine.spi.SharedSessionContractImplementor;
2020
import org.hibernate.engine.spi.SubselectFetch;
21+
import org.hibernate.event.spi.EventManager;
2122
import org.hibernate.event.spi.EventSource;
23+
import org.hibernate.event.spi.HibernateMonitoringEvent;
2224
import org.hibernate.loader.LoaderLogging;
2325
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
2426
import org.hibernate.metamodel.mapping.EntityMappingType;
@@ -107,7 +109,17 @@ public static void upgradeLock(Object object, EntityEntry entry, LockOptions loc
107109
}
108110
else {
109111
if ( entry.isExistsInDatabase() ) {
110-
persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, session );
112+
final EventManager eventManager = session.getEventManager();
113+
final HibernateMonitoringEvent entityLockEvent = eventManager.beginEntityLockEvent();
114+
boolean success = false;
115+
try {
116+
persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, session );
117+
success = true;
118+
}
119+
finally {
120+
eventManager.completeEntityLockEvent( entityLockEvent, entry.getId(),
121+
persister.getEntityName(), lockOptions.getLockMode(), success, session );
122+
}
111123
}
112124
else {
113125
session.forceFlush( entry );
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.event.jfr.internal;
6+
7+
import jdk.jfr.Category;
8+
import jdk.jfr.Description;
9+
import jdk.jfr.Event;
10+
import jdk.jfr.Label;
11+
import jdk.jfr.Name;
12+
import jdk.jfr.StackTrace;
13+
import org.hibernate.LockMode;
14+
import org.hibernate.event.spi.HibernateMonitoringEvent;
15+
import org.hibernate.internal.build.AllowNonPortable;
16+
17+
@Name(EntityLockEvent.NAME)
18+
@Label("Entity Delete")
19+
@Category("Hibernate ORM")
20+
@Description("Entity Delete")
21+
@StackTrace
22+
@AllowNonPortable
23+
public class EntityLockEvent extends Event implements HibernateMonitoringEvent {
24+
public static final String NAME = "org.hibernate.orm.EntityDeleteEvent";
25+
26+
@Label("Session Identifier")
27+
public String sessionIdentifier;
28+
29+
@Label("Entity Identifier")
30+
public String id;
31+
32+
@Label("Entity Name")
33+
public String entityName;
34+
35+
@Label("Lock Mode")
36+
public LockMode lockMode;
37+
38+
@Label("Success")
39+
public boolean success;
40+
41+
@Override
42+
public String toString() {
43+
return NAME;
44+
}
45+
46+
}

hibernate-jfr/src/main/java/org/hibernate/event/jfr/internal/JfrEventManager.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.event.jfr.internal;
66

7+
import org.hibernate.LockMode;
78
import org.hibernate.cache.spi.Region;
89
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
910
import org.hibernate.engine.spi.EntityEntry;
@@ -45,6 +46,7 @@ public class JfrEventManager implements EventManager {
4546
private static final EventType entityUpdateEventType = EventType.getEventType( EntityUpdateEvent.class );
4647
private static final EventType entityUpsertEventType = EventType.getEventType( EntityUpsertEvent.class );
4748
private static final EventType entityDeleteEventType = EventType.getEventType( EntityDeleteEvent.class );
49+
private static final EventType entityLockEventType = EventType.getEventType( EntityLockEvent.class );
4850
private static final EventType collectionRecreateEventType = EventType.getEventType( CollectionRecreateEvent.class );
4951
private static final EventType collectionUpdateEventType = EventType.getEventType( CollectionUpdateEvent.class );
5052
private static final EventType collectionRemoveEventType = EventType.getEventType( CollectionRemoveEvent.class );
@@ -656,6 +658,34 @@ public void completeEntityDeleteEvent(
656658
}
657659
}
658660

661+
@Override
662+
public HibernateMonitoringEvent beginEntityLockEvent() {
663+
if ( entityLockEventType.isEnabled() ) {
664+
final EntityLockEvent event = new EntityLockEvent();
665+
event.begin();
666+
return event;
667+
}
668+
else {
669+
return null;
670+
}
671+
}
672+
673+
@Override
674+
public void completeEntityLockEvent(HibernateMonitoringEvent event, Object id, String entityName, LockMode lockMode, boolean success, SharedSessionContractImplementor session) {
675+
if ( event != null ) {
676+
final EntityLockEvent entityLockEvent = (EntityLockEvent) event;
677+
entityLockEvent.end();
678+
if ( entityLockEvent.shouldCommit() ) {
679+
entityLockEvent.sessionIdentifier = getSessionIdentifier( session );
680+
entityLockEvent.entityName = entityName;
681+
entityLockEvent.id = Objects.toString(id);
682+
entityLockEvent.lockMode = lockMode;
683+
entityLockEvent.success = success;
684+
entityLockEvent.commit();
685+
}
686+
}
687+
}
688+
659689
@Override
660690
public HibernateMonitoringEvent beginCollectionRecreateEvent() {
661691
if ( collectionRecreateEventType.isEnabled() ) {

0 commit comments

Comments
 (0)