Skip to content

Commit d3ce8d4

Browse files
committed
HHH-18942 JFR events for stateless sessions
also add Statistics for upsert
1 parent caed673 commit d3ce8d4

File tree

10 files changed

+266
-71
lines changed

10 files changed

+266
-71
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,16 @@ public void completeEntityUpdateEvent(
266266

267267
}
268268

269+
@Override
270+
public HibernateMonitoringEvent beginEntityUpsertEvent() {
271+
return null;
272+
}
273+
274+
@Override
275+
public void completeEntityUpsertEvent(HibernateMonitoringEvent event, Object id, String entityName, boolean success, SharedSessionContractImplementor session) {
276+
277+
}
278+
269279
@Override
270280
public HibernateMonitoringEvent beginEntityDeleteEvent() {
271281
return null;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ void completePrePartialFlush(
165165

166166
void completeEntityUpdateEvent(HibernateMonitoringEvent event, Object id, String entityName, boolean success, SharedSessionContractImplementor session);
167167

168+
HibernateMonitoringEvent beginEntityUpsertEvent();
169+
170+
void completeEntityUpsertEvent(HibernateMonitoringEvent event, Object id, String entityName, boolean success, SharedSessionContractImplementor session);
171+
168172
HibernateMonitoringEvent beginEntityDeleteEvent();
169173

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

hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ Statements prepared (closed): %s (%s)
799799
Second-level cache hits (misses): %s (%s)
800800
Entities loaded: %s
801801
Entities fetched: %s (minimize this)
802-
Entities updated, inserted, deleted: %s, %s, %s
802+
Entities updated, upserted, inserted, deleted: %s, %s, %s, %s
803803
Collections loaded: %s
804804
Collections fetched: %s (minimize this)
805805
Collections updated, removed, recreated: %s, %s, %s
@@ -833,6 +833,7 @@ void logStatistics(
833833
long entityLoadCount,
834834
long entityFetchCount,
835835
long entityUpdateCount,
836+
long entityUpsertCount,
836837
long entityInsertCount,
837838
long entityDeleteCount,
838839
long collectionLoadCount,

hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java

Lines changed: 115 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.hibernate.engine.spi.PersistenceContext;
3232
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
3333
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
34+
import org.hibernate.event.spi.EventManager;
35+
import org.hibernate.event.spi.HibernateMonitoringEvent;
3436
import org.hibernate.event.spi.PostDeleteEvent;
3537
import org.hibernate.event.spi.PostDeleteEventListener;
3638
import org.hibernate.event.spi.PostInsertEvent;
@@ -184,23 +186,45 @@ else if ( generator.generatedOnExecution( entity, this ) ) {
184186
}
185187
else {
186188
getInterceptor().onInsert( entity, id, state, persister.getPropertyNames(), persister.getPropertyTypes() );
187-
persister.getInsertCoordinator().insert( entity, id, state, this );
189+
final EventManager eventManager = getEventManager();
190+
final HibernateMonitoringEvent event = eventManager.beginEntityInsertEvent();
191+
boolean success = false;
192+
try {
193+
persister.getInsertCoordinator().insert( entity, id, state, this );
194+
success = true;
195+
}
196+
finally {
197+
eventManager.completeEntityInsertEvent( event, id, persister.getEntityName(), success, this );
198+
}
188199
}
189200
}
201+
recreateCollections( entity, id, persister );
202+
firePostInsert(entity, id, state, persister);
203+
final StatisticsImplementor statistics = getFactory().getStatistics();
204+
if ( statistics.isStatisticsEnabled() ) {
205+
statistics.insertEntity( persister.getEntityName() );
206+
}
207+
return id;
208+
}
209+
210+
private void recreateCollections(Object entity, Object id, EntityPersister persister) {
190211
forEachOwnedCollection( entity, id, persister,
191212
(descriptor, collection) -> {
192-
descriptor.recreate( collection, id, this);
213+
final EventManager eventManager = getEventManager();
214+
final HibernateMonitoringEvent event = eventManager.beginCollectionRecreateEvent();
215+
boolean success = false;
216+
try {
217+
descriptor.recreate( collection, id, this );
218+
success = true;
219+
}
220+
finally {
221+
eventManager.completeCollectionRecreateEvent( event, id, descriptor.getRole(), success, this );
222+
}
193223
final StatisticsImplementor statistics = getFactory().getStatistics();
194224
if ( statistics.isStatisticsEnabled() ) {
195225
statistics.recreateCollection( descriptor.getRole() );
196226
}
197227
} );
198-
firePostInsert(entity, id, state, persister);
199-
final StatisticsImplementor statistics = getFactory().getStatistics();
200-
if ( statistics.isStatisticsEnabled() ) {
201-
statistics.insertEntity( persister.getEntityName() );
202-
}
203-
return id;
204228
}
205229

206230
// deletes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -231,17 +255,18 @@ public void delete(String entityName, Object entity) {
231255
final Object id = persister.getIdentifier( entity, this );
232256
final Object version = persister.getVersion( entity );
233257
if ( !firePreDelete(entity, id, persister) ) {
234-
getInterceptor()
235-
.onDelete( entity, id, persister.getPropertyNames(), persister.getPropertyTypes() );
236-
forEachOwnedCollection( entity, id, persister,
237-
(descriptor, collection) -> {
238-
descriptor.remove( id, this );
239-
final StatisticsImplementor statistics = getFactory().getStatistics();
240-
if ( statistics.isStatisticsEnabled() ) {
241-
statistics.removeCollection( descriptor.getRole() );
242-
}
243-
} );
244-
persister.getDeleteCoordinator().delete( entity, id, version, this );
258+
getInterceptor().onDelete( entity, id, persister.getPropertyNames(), persister.getPropertyTypes() );
259+
removeCollections( entity, id, persister );
260+
final EventManager eventManager = getEventManager();
261+
final HibernateMonitoringEvent event = eventManager.beginEntityDeleteEvent();
262+
boolean success = false;
263+
try {
264+
persister.getDeleteCoordinator().delete( entity, id, version, this );
265+
success = true;
266+
}
267+
finally {
268+
eventManager.completeEntityDeleteEvent( event, id, persister.getEntityName(), success, this );
269+
}
245270
firePostDelete(entity, id, persister);
246271
final StatisticsImplementor statistics = getFactory().getStatistics();
247272
if ( statistics.isStatisticsEnabled() ) {
@@ -250,6 +275,27 @@ public void delete(String entityName, Object entity) {
250275
}
251276
}
252277

278+
private void removeCollections(Object entity, Object id, EntityPersister persister) {
279+
forEachOwnedCollection( entity, id, persister,
280+
(descriptor, collection) -> {
281+
final EventManager eventManager = getEventManager();
282+
final HibernateMonitoringEvent event = eventManager.beginCollectionRemoveEvent();
283+
boolean success = false;
284+
try {
285+
descriptor.remove( id, this );
286+
success = true;
287+
}
288+
finally {
289+
eventManager.completeCollectionRemoveEvent( event, id, descriptor.getRole(), success, this );
290+
}
291+
292+
final StatisticsImplementor statistics = getFactory().getStatistics();
293+
if ( statistics.isStatisticsEnabled() ) {
294+
statistics.removeCollection( descriptor.getRole() );
295+
}
296+
} );
297+
}
298+
253299

254300
// updates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
255301

@@ -289,19 +335,18 @@ public void update(String entityName, Object entity) {
289335
oldVersion = null;
290336
}
291337
if ( !firePreUpdate(entity, id, state, persister) ) {
292-
getInterceptor()
293-
.onUpdate( entity, id, state, persister.getPropertyNames(), persister.getPropertyTypes() );
294-
persister.getUpdateCoordinator().update( entity, id, null, state, oldVersion, null, null, false, this );
295-
forEachOwnedCollection( entity, id, persister,
296-
(descriptor, collection) -> {
297-
// TODO: can we do better here?
298-
descriptor.remove( id, this );
299-
descriptor.recreate( collection, id, this );
300-
final StatisticsImplementor statistics = getFactory().getStatistics();
301-
if ( statistics.isStatisticsEnabled() ) {
302-
statistics.updateCollection( descriptor.getRole() );
303-
}
304-
} );
338+
getInterceptor().onUpdate( entity, id, state, persister.getPropertyNames(), persister.getPropertyTypes() );
339+
final EventManager eventManager = getEventManager();
340+
final HibernateMonitoringEvent event = eventManager.beginEntityUpdateEvent();
341+
boolean success = false;
342+
try {
343+
persister.getUpdateCoordinator().update( entity, id, null, state, oldVersion, null, null, false, this );
344+
success = true;
345+
}
346+
finally {
347+
eventManager.completeEntityUpdateEvent( event, id, persister.getEntityName(), success, this );
348+
}
349+
removeAndRecreateCollections( entity, id, persister );
305350
firePostUpdate(entity, id, state, persister);
306351
final StatisticsImplementor statistics = getFactory().getStatistics();
307352
if ( statistics.isStatisticsEnabled() ) {
@@ -310,6 +355,28 @@ public void update(String entityName, Object entity) {
310355
}
311356
}
312357

358+
private void removeAndRecreateCollections(Object entity, Object id, EntityPersister persister) {
359+
forEachOwnedCollection( entity, id, persister,
360+
(descriptor, collection) -> {
361+
final EventManager eventManager = getEventManager();
362+
final HibernateMonitoringEvent event = eventManager.beginCollectionRemoveEvent();
363+
boolean success = false;
364+
try {
365+
// TODO: can we do better here?
366+
descriptor.remove( id, this );
367+
descriptor.recreate( collection, id, this );
368+
success = true;
369+
}
370+
finally {
371+
eventManager.completeCollectionRemoveEvent( event, id, descriptor.getRole(), success, this );
372+
}
373+
final StatisticsImplementor statistics = getFactory().getStatistics();
374+
if ( statistics.isStatisticsEnabled() ) {
375+
statistics.updateCollection( descriptor.getRole() );
376+
}
377+
} );
378+
}
379+
313380
@Override
314381
public void upsert(Object entity) {
315382
upsert( null, entity );
@@ -336,21 +403,23 @@ public void upsert(String entityName, Object entity) {
336403
final Object id = idToUpsert( entity, persister );
337404
final Object[] state = persister.getValues( entity );
338405
if ( !firePreUpsert(entity, id, state, persister) ) {
339-
getInterceptor()
340-
.onUpsert( entity, id, state, persister.getPropertyNames(), persister.getPropertyTypes() );
406+
getInterceptor().onUpsert( entity, id, state, persister.getPropertyNames(), persister.getPropertyTypes() );
341407
final Object oldVersion = versionToUpsert( entity, persister, state );
342-
persister.getMergeCoordinator().update( entity, id, null, state, oldVersion, null, null, false, this );
343-
// TODO: statistics for upsert!
344-
forEachOwnedCollection( entity, id, persister,
345-
(descriptor, collection) -> {
346-
// TODO: can we do better here?
347-
descriptor.remove( id, this );
348-
descriptor.recreate( collection, id, this );
349-
final StatisticsImplementor statistics = getFactory().getStatistics();
350-
if ( statistics.isStatisticsEnabled() ) {
351-
statistics.updateCollection( descriptor.getRole() );
352-
}
353-
} );
408+
final EventManager eventManager = getEventManager();
409+
final HibernateMonitoringEvent event = eventManager.beginEntityUpsertEvent();
410+
boolean success = false;
411+
try {
412+
persister.getMergeCoordinator().update( entity, id, null, state, oldVersion, null, null, false, this );
413+
success = true;
414+
}
415+
finally {
416+
eventManager.completeEntityUpsertEvent( event, id, persister.getEntityName(), success, this );
417+
}
418+
final StatisticsImplementor statistics = getFactory().getStatistics();
419+
if ( statistics.isStatisticsEnabled() ) {
420+
statistics.upsertEntity( persister.getEntityName() );
421+
}
422+
removeAndRecreateCollections( entity, id, persister );
354423
firePostUpsert(entity, id, state, persister);
355424
}
356425
}

hibernate-core/src/main/java/org/hibernate/stat/Statistics.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ public interface Statistics {
156156
*/
157157
long getEntityUpdateCount();
158158

159+
/**
160+
* The global number of entity upserts.
161+
*/
162+
long getEntityUpsertCount();
163+
159164
/**
160165
* The global number of executed queries.
161166
*/

hibernate-core/src/main/java/org/hibernate/stat/internal/EntityStatisticsImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class EntityStatisticsImpl extends AbstractCacheableDataStatistics implem
2020
private final String rootEntityName;
2121
private final LongAdder loadCount = new LongAdder();
2222
private final LongAdder updateCount = new LongAdder();
23+
private final LongAdder upsertCount = new LongAdder();
2324
private final LongAdder insertCount = new LongAdder();
2425
private final LongAdder deleteCount = new LongAdder();
2526
private final LongAdder fetchCount = new LongAdder();
@@ -50,6 +51,10 @@ public long getUpdateCount() {
5051
return updateCount.sum();
5152
}
5253

54+
public long getUpsertCount() {
55+
return upsertCount.sum();
56+
}
57+
5358
public long getFetchCount() {
5459
return fetchCount.sum();
5560
}
@@ -70,6 +75,10 @@ void incrementUpdateCount() {
7075
updateCount.increment();
7176
}
7277

78+
void incrementUpsertCount() {
79+
upsertCount.increment();
80+
}
81+
7382
void incrementInsertCount() {
7483
insertCount.increment();
7584
}
@@ -88,6 +97,7 @@ public String toString() {
8897
.append( "[rootEntityName=" ).append( rootEntityName )
8998
.append( ",loadCount=" ).append( this.loadCount )
9099
.append( ",updateCount=" ).append( this.updateCount )
100+
.append( ",upsertCount=" ).append( this.upsertCount )
91101
.append( ",insertCount=" ).append( this.insertCount )
92102
.append( ",deleteCount=" ).append( this.deleteCount )
93103
.append( ",fetchCount=" ).append( this.fetchCount )

hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
6666

6767
private final LongAdder entityLoadCount = new LongAdder();
6868
private final LongAdder entityUpdateCount = new LongAdder();
69+
private final LongAdder entityUpsertCount = new LongAdder();
6970
private final LongAdder entityInsertCount = new LongAdder();
7071
private final LongAdder entityDeleteCount = new LongAdder();
7172
private final LongAdder entityFetchCount = new LongAdder();
@@ -174,6 +175,7 @@ public void clear() {
174175
entityDeleteCount.reset();
175176
entityInsertCount.reset();
176177
entityUpdateCount.reset();
178+
entityUpsertCount.reset();
177179
entityLoadCount.reset();
178180
entityFetchCount.reset();
179181

@@ -280,6 +282,11 @@ public long getEntityUpdateCount() {
280282
return entityUpdateCount.sum();
281283
}
282284

285+
@Override
286+
public long getEntityUpsertCount() {
287+
return entityUpsertCount.sum();
288+
}
289+
283290
@Override
284291
public long getOptimisticFailureCount() {
285292
return optimisticFailureCount.sum();
@@ -303,6 +310,12 @@ public void updateEntity(String entityName) {
303310
getEntityStatistics( entityName ).incrementUpdateCount();
304311
}
305312

313+
@Override
314+
public void upsertEntity(String entityName) {
315+
entityUpsertCount.increment();
316+
getEntityStatistics( entityName ).incrementUpsertCount();
317+
}
318+
306319
@Override
307320
public void insertEntity(String entityName) {
308321
entityInsertCount.increment();
@@ -901,6 +914,7 @@ public void logSummary() {
901914
entityLoadCount.sum(),
902915
entityFetchCount.sum(),
903916
entityUpdateCount.sum(),
917+
entityUpsertCount.sum(),
904918
entityInsertCount.sum(),
905919
entityDeleteCount.sum(),
906920
collectionLoadCount.sum(),
@@ -944,6 +958,7 @@ public String toString() {
944958
",second level cache misses=" + secondLevelCacheMissCount +
945959
",entities loaded=" + entityLoadCount +
946960
",entities updated=" + entityUpdateCount +
961+
",entities upserted=" + entityUpsertCount +
947962
",entities inserted=" + entityInsertCount +
948963
",entities deleted=" + entityDeleteCount +
949964
",entities fetched=" + entityFetchCount +

hibernate-core/src/main/java/org/hibernate/stat/spi/StatisticsImplementor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ public interface StatisticsImplementor extends Statistics, Service {
8080
*/
8181
void updateEntity(String entityName);
8282

83+
/**
84+
* Callback about an entity being upserted.
85+
*
86+
* @param entityName The name of the entity upserted.
87+
*/
88+
void upsertEntity(String entityName);
89+
8390
/**
8491
* Callback about an entity being inserted
8592
*

0 commit comments

Comments
 (0)