Skip to content

Commit 119cd8b

Browse files
committed
introduce PreFlushEvent
1 parent 76ebaee commit 119cd8b

File tree

12 files changed

+102
-33
lines changed

12 files changed

+102
-33
lines changed

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
6161
import org.hibernate.query.criteria.JpaCriteriaInsert;
6262
import org.hibernate.query.spi.QueryImplementor;
63+
import org.hibernate.query.spi.QueryParameterBindings;
6364
import org.hibernate.query.spi.QueryProducerImplementor;
6465
import org.hibernate.query.sql.spi.NativeQueryImplementor;
6566
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
@@ -418,8 +419,8 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
418419
}
419420

420421
@Override
421-
public void autoPreFlush(Set<String> querySpaces) {
422-
delegate.autoPreFlush( querySpaces );
422+
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
423+
return delegate.autoPreFlushIfRequired( parameterBindings );
423424
}
424425

425426
@Override

hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
3030
import org.hibernate.engine.jdbc.spi.JdbcServices;
3131
import org.hibernate.persister.entity.EntityPersister;
32+
import org.hibernate.query.spi.QueryParameterBindings;
3233
import org.hibernate.query.spi.QueryProducerImplementor;
3334
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
3435
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
@@ -535,7 +536,7 @@ default boolean autoFlushIfRequired(Set<String> querySpaces) {
535536
*/
536537
boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush);
537538

538-
void autoPreFlush(Set<String> querySpaces);
539+
boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings);
539540

540541
/**
541542
* Check if there is a Hibernate or JTA transaction in progress and,

hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
4141
import org.hibernate.query.criteria.JpaCriteriaInsert;
4242
import org.hibernate.query.spi.QueryImplementor;
43+
import org.hibernate.query.spi.QueryParameterBindings;
4344
import org.hibernate.query.spi.QueryProducerImplementor;
4445
import org.hibernate.query.sql.spi.NativeQueryImplementor;
4546
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
@@ -569,8 +570,8 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
569570
}
570571

571572
@Override
572-
public void autoPreFlush(Set<String> querySpaces) {
573-
delegate.autoPreFlush( querySpaces );
573+
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
574+
return delegate.autoPreFlushIfRequired( parameterBindings );
574575
}
575576

576577
@Override

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
8181
}
8282
}
8383

84-
static boolean flushIsReallyNeeded(AutoFlushEvent event, EventSource source) {
84+
private static boolean flushIsReallyNeeded(AutoFlushEvent event, EventSource source) {
8585
return source.getHibernateFlushMode() == FlushMode.ALWAYS
8686
|| source.getActionQueue().areTablesToBeUpdated( event.getQuerySpaces() );
8787
}
8888

89-
static boolean flushMightBeNeeded(AutoFlushEvent event, EventSource source) {
89+
private static boolean flushMightBeNeeded(AutoFlushEvent event, EventSource source) {
9090
return flushMightBeNeededForMode( event, source )
9191
&& nonEmpty( source );
9292
}

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@
55
package org.hibernate.event.internal;
66

77
import org.hibernate.HibernateException;
8-
import org.hibernate.event.spi.AutoFlushEvent;
8+
import org.hibernate.event.spi.EventSource;
9+
import org.hibernate.event.spi.PreFlushEvent;
910
import org.hibernate.event.spi.PreFlushEventListener;
1011

11-
import static org.hibernate.event.internal.DefaultAutoFlushEventListener.flushMightBeNeeded;
12-
1312
public class DefaultPreFlushEventListener extends AbstractFlushingEventListener implements PreFlushEventListener {
13+
1414
@Override
15-
public void onAutoPreFlush(AutoFlushEvent event) throws HibernateException {
15+
public void onAutoPreFlush(PreFlushEvent event) throws HibernateException {
1616
final var source = event.getEventSource();
1717
final var eventListenerManager = source.getEventListenerManager();
1818
eventListenerManager.prePartialFlushStart();
1919
final var eventMonitor = source.getEventMonitor();
2020
final var diagnosticEvent = eventMonitor.beginPrePartialFlush();
2121
try {
22-
if ( flushMightBeNeeded( event, source ) ) {
22+
if ( preFlushMightBeNeeded( source )
23+
&& event.getParameterBindings().hasAnyTransientEntityBindings( source ) ) {
2324
preFlush( source, source.getPersistenceContextInternal() );
2425
}
2526
}
@@ -28,4 +29,23 @@ public void onAutoPreFlush(AutoFlushEvent event) throws HibernateException {
2829
eventListenerManager.prePartialFlushEnd();
2930
}
3031
}
32+
33+
34+
private static boolean preFlushMightBeNeeded(EventSource source) {
35+
return flushMightBeNeededForMode( source )
36+
&& nonEmpty( source );
37+
}
38+
39+
private static boolean flushMightBeNeededForMode(EventSource source) {
40+
return switch ( source.getHibernateFlushMode() ) {
41+
case ALWAYS, AUTO -> true;
42+
case MANUAL, COMMIT -> false;
43+
};
44+
}
45+
46+
private static boolean nonEmpty(EventSource source) {
47+
final var persistenceContext = source.getPersistenceContextInternal();
48+
return persistenceContext.getNumberOfManagedEntities() > 0
49+
|| persistenceContext.getCollectionEntriesSize() > 0;
50+
}
3151
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.event.spi;
6+
7+
import org.hibernate.Incubating;
8+
import org.hibernate.query.spi.QueryParameterBindings;
9+
10+
/**
11+
* An event that occurs just before arguments are bound to JDBC
12+
* parameters during execution of HQL. Gives Hibernate a chance
13+
* to persist any transient entities used as query parameter
14+
* arguments.
15+
*
16+
* @author Gavin King
17+
* @since 7.2
18+
*/
19+
@Incubating
20+
public class PreFlushEvent extends AbstractSessionEvent {
21+
22+
private boolean preFlushRequired;
23+
private final QueryParameterBindings parameterBindings;
24+
25+
public PreFlushEvent(QueryParameterBindings parameterBindings, EventSource source) {
26+
super( source );
27+
this.parameterBindings = parameterBindings;
28+
}
29+
30+
public QueryParameterBindings getParameterBindings() {
31+
return parameterBindings;
32+
}
33+
34+
public boolean isPreFlushRequired() {
35+
return preFlushRequired;
36+
}
37+
38+
public void setPreFlushRequired(boolean preFlushRequired) {
39+
this.preFlushRequired = preFlushRequired;
40+
}
41+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
package org.hibernate.event.spi;
66

77
import org.hibernate.HibernateException;
8+
import org.hibernate.Incubating;
89

910
/**
11+
* A listener for events of type {@link PreFlushEvent}.
12+
*
1013
* @author Gavin King
1114
* @since 7.2
1215
*/
16+
@Incubating
1317
public interface PreFlushEventListener {
14-
void onAutoPreFlush(AutoFlushEvent event) throws HibernateException;
18+
void onAutoPreFlush(PreFlushEvent event) throws HibernateException;
1519
}

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.hibernate.query.SelectionQuery;
6262
import org.hibernate.query.UnknownSqlResultSetMappingException;
6363
import org.hibernate.query.spi.QueryImplementor;
64+
import org.hibernate.query.spi.QueryParameterBindings;
6465
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
6566
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
6667
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
@@ -1437,15 +1438,17 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
14371438
}
14381439

14391440
@Override
1440-
public void autoPreFlush(Set<String> querySpaces) {
1441+
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
14411442
checkOpen();
1442-
// do not auto-flush while outside a transaction
1443-
if ( isTransactionInProgress() ) {
1444-
final var autoFlushEvent = new AutoFlushEvent( querySpaces, false, this );
1445-
eventListenerGroups.eventListenerGroup_PRE_FLUSH
1446-
.fireEventOnEachListener( autoFlushEvent,
1447-
PreFlushEventListener::onAutoPreFlush );
1443+
if ( !isTransactionInProgress() ) {
1444+
// do not auto-flush while outside a transaction
1445+
return false;
14481446
}
1447+
final var preFlushEvent = new PreFlushEvent( parameterBindings, this );
1448+
eventListenerGroups.eventListenerGroup_PRE_FLUSH
1449+
.fireEventOnEachListener( preFlushEvent,
1450+
PreFlushEventListener::onAutoPreFlush );
1451+
return preFlushEvent.isPreFlushRequired();
14491452
}
14501453

14511454
@Override

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import org.hibernate.loader.internal.CacheLoadHelper;
7070
import org.hibernate.persister.collection.CollectionPersister;
7171
import org.hibernate.persister.entity.EntityPersister;
72+
import org.hibernate.query.spi.QueryParameterBindings;
7273
import org.hibernate.stat.spi.StatisticsImplementor;
7374

7475
import java.util.List;
@@ -1325,7 +1326,8 @@ public void afterScrollOperation() {
13251326
}
13261327

13271328
@Override
1328-
public void autoPreFlush(Set<String> querySpaces) {
1329+
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
1330+
return false;
13291331
}
13301332

13311333
@Override

hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureParamBindings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public boolean hasAnyMultiValuedBindings() {
121121
}
122122

123123
@Override
124-
public boolean hasAnyTransientEntityBindings(SharedSessionContractImplementor factory) {
124+
public boolean hasAnyTransientEntityBindings(SharedSessionContractImplementor session) {
125125
return false;
126126
}
127127

@@ -131,7 +131,7 @@ public void visitBindings(BiConsumer<? super QueryParameter<?>, ? super QueryPar
131131
}
132132

133133
@Override
134-
public QueryKey.ParameterBindingsMemento generateQueryKeyMemento(SharedSessionContractImplementor persistenceContext) {
134+
public QueryKey.ParameterBindingsMemento generateQueryKeyMemento(SharedSessionContractImplementor session) {
135135
return NO_PARAMETER_BINDING_MEMENTO;
136136
}
137137
}

0 commit comments

Comments
 (0)