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 @@ -588,25 +588,20 @@ public boolean areTablesToBeUpdated(Set<? extends Serializable> tables) {
return true;
}
}
if ( unresolvedInsertions == null ) {
return false;
}
return areTablesToBeUpdated( unresolvedInsertions, tables );
return unresolvedInsertions != null
&& areTablesToBeUpdated( unresolvedInsertions, tables );
}

private static boolean areTablesToBeUpdated(@Nullable ExecutableList<?> queue, Set<? extends Serializable> tableSpaces) {
if ( queue == null || queue.isEmpty() ) {
return false;
}
else {
if ( queue != null && !queue.isEmpty() ) {
for ( var actionSpace : queue.getQuerySpaces() ) {
if ( tableSpaces.contains( actionSpace ) ) {
ACTION_LOGGER.changesMustBeFlushedToSpace( actionSpace );
return true;
}
}
return false;
}
return false;
}

private static boolean areTablesToBeUpdated(UnresolvedEntityInsertActions actions, Set<? extends Serializable> tableSpaces) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaInsert;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryProducerImplementor;
import org.hibernate.query.sql.spi.NativeQueryImplementor;
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
Expand Down Expand Up @@ -418,8 +419,8 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
}

@Override
public void autoPreFlush() {
delegate.autoPreFlush();
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
return delegate.autoPreFlushIfRequired( parameterBindings );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryProducerImplementor;
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
Expand Down Expand Up @@ -535,7 +536,7 @@ default boolean autoFlushIfRequired(Set<String> querySpaces) {
*/
boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush);

void autoPreFlush();
boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings);

/**
* Check if there is a Hibernate or JTA transaction in progress and,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaInsert;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryProducerImplementor;
import org.hibernate.query.sql.spi.NativeQueryImplementor;
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
Expand Down Expand Up @@ -569,8 +570,8 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
}

@Override
public void autoPreFlush() {
delegate.autoPreFlush();
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
return delegate.autoPreFlushIfRequired( parameterBindings );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ protected void logFlushResults(FlushEvent event) {
}

/**
* Process cascade save/update at the start of a flush to discover
* any newly referenced entity that must be passed to saveOrUpdate(),
* and also apply orphan delete
* Process {@link CascadingActions#PERSIST_ON_FLUSH} at the start of a
* flush to discover any newly referenced entity that must be passed to
* {@code persist()}, and also apply orphan delete.
*/
private void prepareEntityFlushes(EventSource session, PersistenceContext persistenceContext)
throws HibernateException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
final var partialFlushEvent = eventMonitor.beginPartialFlushEvent();
try {
eventListenerManager.partialFlushStart();

if ( flushMightBeNeeded( source ) ) {
if ( flushMightBeNeeded( event, source ) ) {
// Need to get the number of collection removals before flushing to executions
// (because flushing to executions can add collection removal actions to the action queue).
final var actionQueue = source.getActionQueue();
Expand Down Expand Up @@ -82,32 +81,30 @@ public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
}
}

@Override
public void onAutoPreFlush(EventSource source) throws HibernateException {
final var eventListenerManager = source.getEventListenerManager();
eventListenerManager.prePartialFlushStart();
final var eventMonitor = source.getEventMonitor();
final var diagnosticEvent = eventMonitor.beginPrePartialFlush();
try {
if ( flushMightBeNeeded( source ) ) {
preFlush( source, source.getPersistenceContextInternal() );
}
}
finally {
eventMonitor.completePrePartialFlush( diagnosticEvent, source );
eventListenerManager.prePartialFlushEnd();
}
}

private boolean flushIsReallyNeeded(AutoFlushEvent event, final EventSource source) {
private static boolean flushIsReallyNeeded(AutoFlushEvent event, EventSource source) {
return source.getHibernateFlushMode() == FlushMode.ALWAYS
|| source.getActionQueue().areTablesToBeUpdated( event.getQuerySpaces() );
}

private boolean flushMightBeNeeded(final EventSource source) {
private static boolean flushMightBeNeeded(AutoFlushEvent event, EventSource source) {
return flushMightBeNeededForMode( event, source )
&& nonEmpty( source );
}

private static boolean flushMightBeNeededForMode(AutoFlushEvent event, EventSource source) {
return switch ( source.getHibernateFlushMode() ) {
case ALWAYS -> true;
case AUTO -> {
final var querySpaces = event.getQuerySpaces();
yield querySpaces == null || !querySpaces.isEmpty();
}
case MANUAL, COMMIT -> false;
};
}

private static boolean nonEmpty(EventSource source) {
final var persistenceContext = source.getPersistenceContextInternal();
return !source.getHibernateFlushMode().lessThan( FlushMode.AUTO )
&& ( persistenceContext.getNumberOfManagedEntities() > 0
|| persistenceContext.getCollectionEntriesSize() > 0 );
return persistenceContext.getNumberOfManagedEntities() > 0
|| persistenceContext.getCollectionEntriesSize() > 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.event.internal;

import org.hibernate.HibernateException;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.PreFlushEvent;
import org.hibernate.event.spi.PreFlushEventListener;

public class DefaultPreFlushEventListener extends AbstractFlushingEventListener implements PreFlushEventListener {

@Override
public void onAutoPreFlush(PreFlushEvent event) throws HibernateException {
final var source = event.getEventSource();
final var eventListenerManager = source.getEventListenerManager();
eventListenerManager.prePartialFlushStart();
final var eventMonitor = source.getEventMonitor();
final var diagnosticEvent = eventMonitor.beginPrePartialFlush();
try {
if ( preFlushMightBeNeeded( source )
&& event.getParameterBindings().hasAnyTransientEntityBindings( source ) ) {
preFlush( source, source.getPersistenceContextInternal() );
}
}
finally {
eventMonitor.completePrePartialFlush( diagnosticEvent, source );
eventListenerManager.prePartialFlushEnd();
}
}


private static boolean preFlushMightBeNeeded(EventSource source) {
return flushMightBeNeededForMode( source )
&& nonEmpty( source );
}

private static boolean flushMightBeNeededForMode(EventSource source) {
return switch ( source.getHibernateFlushMode() ) {
case ALWAYS, AUTO -> true;
case MANUAL, COMMIT -> false;
};
}

private static boolean nonEmpty(EventSource source) {
final var persistenceContext = source.getPersistenceContextInternal();
return persistenceContext.getNumberOfManagedEntities() > 0
|| persistenceContext.getCollectionEntriesSize() > 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.hibernate.event.internal.DefaultPersistEventListener;
import org.hibernate.event.internal.DefaultPersistOnFlushEventListener;
import org.hibernate.event.internal.DefaultPostLoadEventListener;
import org.hibernate.event.internal.DefaultPreFlushEventListener;
import org.hibernate.event.internal.DefaultPreLoadEventListener;
import org.hibernate.event.internal.DefaultRefreshEventListener;
import org.hibernate.event.internal.DefaultReplicateEventListener;
Expand Down Expand Up @@ -69,6 +70,7 @@
import static org.hibernate.event.spi.EventType.PRE_COLLECTION_REMOVE;
import static org.hibernate.event.spi.EventType.PRE_COLLECTION_UPDATE;
import static org.hibernate.event.spi.EventType.PRE_DELETE;
import static org.hibernate.event.spi.EventType.PRE_FLUSH;
import static org.hibernate.event.spi.EventType.PRE_INSERT;
import static org.hibernate.event.spi.EventType.PRE_LOAD;
import static org.hibernate.event.spi.EventType.PRE_UPDATE;
Expand Down Expand Up @@ -216,6 +218,9 @@ private void applyStandardListeners() {
// auto-flush listeners
prepareListeners( AUTO_FLUSH, new DefaultAutoFlushEventListener() );

// pre-flush listeners
prepareListeners( PRE_FLUSH, new DefaultPreFlushEventListener() );

// create listeners
prepareListeners( PERSIST, new DefaultPersistEventListener() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.hibernate.event.spi.PreCollectionRemoveEventListener;
import org.hibernate.event.spi.PreCollectionUpdateEventListener;
import org.hibernate.event.spi.PreDeleteEventListener;
import org.hibernate.event.spi.PreFlushEventListener;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.event.spi.PreLoadEventListener;
import org.hibernate.event.spi.PreUpdateEventListener;
Expand All @@ -57,6 +58,7 @@ public final class EventListenerGroups {
// All session events need to be iterated frequently;
// CollectionAction and EventAction also need most of these very frequently:
public final EventListenerGroup<AutoFlushEventListener> eventListenerGroup_AUTO_FLUSH;
public final EventListenerGroup<PreFlushEventListener> eventListenerGroup_PRE_FLUSH;
public final EventListenerGroup<ClearEventListener> eventListenerGroup_CLEAR;
public final EventListenerGroup<DeleteEventListener> eventListenerGroup_DELETE;
public final EventListenerGroup<DirtyCheckEventListener> eventListenerGroup_DIRTY_CHECK;
Expand Down Expand Up @@ -103,6 +105,7 @@ public EventListenerGroups(ServiceRegistry serviceRegistry) {
// Pre-compute all iterators on Event listeners:

eventListenerGroup_AUTO_FLUSH = listeners( eventListenerRegistry, AUTO_FLUSH );
eventListenerGroup_PRE_FLUSH = listeners( eventListenerRegistry, PRE_FLUSH );
eventListenerGroup_CLEAR = listeners( eventListenerRegistry, CLEAR );
eventListenerGroup_DELETE = listeners( eventListenerRegistry, DELETE );
eventListenerGroup_DIRTY_CHECK = listeners( eventListenerRegistry, DIRTY_CHECK );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,4 @@ public interface AutoFlushEventListener {
* @param event The auto-flush event to be handled.
*/
void onAutoFlush(AutoFlushEvent event) throws HibernateException;

default void onAutoPreFlush(EventSource source) throws HibernateException {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public final class EventType<T> {

public static final EventType<FlushEventListener> FLUSH = create( "flush", FlushEventListener.class );
public static final EventType<AutoFlushEventListener> AUTO_FLUSH = create( "auto-flush", AutoFlushEventListener.class );
public static final EventType<PreFlushEventListener> PRE_FLUSH = create( "pre-flush", PreFlushEventListener.class );
public static final EventType<DirtyCheckEventListener> DIRTY_CHECK = create( "dirty-check", DirtyCheckEventListener.class );
public static final EventType<FlushEntityEventListener> FLUSH_ENTITY = create( "flush-entity", FlushEntityEventListener.class );

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.event.spi;

import org.hibernate.Incubating;
import org.hibernate.query.spi.QueryParameterBindings;

/**
* An event that occurs just before arguments are bound to JDBC
* parameters during execution of HQL. Gives Hibernate a chance
* to persist any transient entities used as query parameter
* arguments.
*
* @author Gavin King
* @since 7.2
*/
@Incubating
public class PreFlushEvent extends AbstractSessionEvent {

private boolean preFlushRequired;
private final QueryParameterBindings parameterBindings;

public PreFlushEvent(QueryParameterBindings parameterBindings, EventSource source) {
super( source );
this.parameterBindings = parameterBindings;
}

public QueryParameterBindings getParameterBindings() {
return parameterBindings;
}

public boolean isPreFlushRequired() {
return preFlushRequired;
}

public void setPreFlushRequired(boolean preFlushRequired) {
this.preFlushRequired = preFlushRequired;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.event.spi;

import org.hibernate.HibernateException;
import org.hibernate.Incubating;

/**
* A listener for events of type {@link PreFlushEvent}.
*
* @author Gavin King
* @since 7.2
*/
@Incubating
public interface PreFlushEventListener {
void onAutoPreFlush(PreFlushEvent event) throws HibernateException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.hibernate.query.SelectionQuery;
import org.hibernate.query.UnknownSqlResultSetMappingException;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
Expand Down Expand Up @@ -1437,14 +1438,17 @@ public boolean autoFlushIfRequired(Set<String> querySpaces, boolean skipPreFlush
}

@Override
public void autoPreFlush() {
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
checkOpen();
// do not auto-flush while outside a transaction
if ( isTransactionInProgress() ) {
eventListenerGroups.eventListenerGroup_AUTO_FLUSH
.fireEventOnEachListener( this,
AutoFlushEventListener::onAutoPreFlush );
if ( !isTransactionInProgress() ) {
// do not auto-flush while outside a transaction
return false;
}
final var preFlushEvent = new PreFlushEvent( parameterBindings, this );
eventListenerGroups.eventListenerGroup_PRE_FLUSH
.fireEventOnEachListener( preFlushEvent,
PreFlushEventListener::onAutoPreFlush );
return preFlushEvent.isPreFlushRequired();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import org.hibernate.loader.internal.CacheLoadHelper;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.stat.spi.StatisticsImplementor;

import java.util.List;
Expand Down Expand Up @@ -1325,7 +1326,8 @@ public void afterScrollOperation() {
}

@Override
public void autoPreFlush() {
public boolean autoPreFlushIfRequired(QueryParameterBindings parameterBindings) {
return false;
}

@Override
Expand Down
Loading