HHH-16695 add enableFetchProfile() to XxxxIdLoadAccess

This commit is contained in:
Gavin King 2023-07-08 22:41:46 +02:00
parent 2e351831f1
commit 09f110254f
13 changed files with 196 additions and 106 deletions

View File

@ -104,6 +104,10 @@ public interface IdentifierLoadAccess<T> {
*/ */
IdentifierLoadAccess<T> with(RootGraph<T> graph, GraphSemantic semantic); IdentifierLoadAccess<T> with(RootGraph<T> graph, GraphSemantic semantic);
IdentifierLoadAccess<T> enableFetchProfile(String profileName);
IdentifierLoadAccess<T> disableFetchProfile(String profileName);
/** /**
* Return the persistent instance with the given identifier, assuming * Return the persistent instance with the given identifier, assuming
* that the instance exists. This method might return a proxied instance * that the instance exists. This method might return a proxied instance

View File

@ -44,6 +44,10 @@ public interface NaturalIdLoadAccess<T> {
*/ */
NaturalIdLoadAccess<T> with(LockOptions lockOptions); NaturalIdLoadAccess<T> with(LockOptions lockOptions);
NaturalIdLoadAccess<T> enableFetchProfile(String profileName);
NaturalIdLoadAccess<T> disableFetchProfile(String profileName);
/** /**
* Add a {@link org.hibernate.annotations.NaturalId @NaturalId} * Add a {@link org.hibernate.annotations.NaturalId @NaturalId}
* attribute value in a typesafe way. * attribute value in a typesafe way.

View File

@ -37,6 +37,10 @@ public interface SimpleNaturalIdLoadAccess<T> {
*/ */
SimpleNaturalIdLoadAccess<T> with(LockOptions lockOptions); SimpleNaturalIdLoadAccess<T> with(LockOptions lockOptions);
SimpleNaturalIdLoadAccess<T> enableFetchProfile(String profileName);
SimpleNaturalIdLoadAccess<T> disableFetchProfile(String profileName);
/** /**
* For entities with mutable natural ids, should Hibernate perform * For entities with mutable natural ids, should Hibernate perform
* "synchronization" prior to performing lookups? The default is * "synchronization" prior to performing lookups? The default is

View File

@ -260,6 +260,19 @@ public class LoadQueryInfluencers implements Serializable {
} }
} }
@Internal
public HashSet<String> adjustFetchProfiles(Set<String> disabledFetchProfiles, Set<String> enabledFetchProfiles) {
final HashSet<String> oldFetchProfiles =
hasEnabledFetchProfiles() ? new HashSet<>( enabledFetchProfileNames ) : null;
if ( disabledFetchProfiles != null ) {
enabledFetchProfileNames.removeAll( disabledFetchProfiles );
}
if ( enabledFetchProfiles != null ) {
enabledFetchProfileNames.addAll( enabledFetchProfiles );
}
return oldFetchProfiles;
}
@Internal @Internal
public void setEnabledFetchProfileNames(HashSet<String> enabledFetchProfileNames) { public void setEnabledFetchProfileNames(HashSet<String> enabledFetchProfileNames) {
this.enabledFetchProfileNames = enabledFetchProfileNames; this.enabledFetchProfileNames = enabledFetchProfileNames;

View File

@ -13,7 +13,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -7,13 +7,16 @@
package org.hibernate.loader.internal; package org.hibernate.loader.internal;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.IdentifierLoadAccess; import org.hibernate.IdentifierLoadAccess;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status; import org.hibernate.engine.spi.Status;
@ -39,6 +42,9 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
private LockOptions lockOptions; private LockOptions lockOptions;
private boolean synchronizationEnabled = true; private boolean synchronizationEnabled = true;
private Set<String> enabledFetchProfiles;
private Set<String> disabledFetchProfiles;
protected BaseNaturalIdLoadAccessImpl(LoadAccessContext context, EntityMappingType entityDescriptor) { protected BaseNaturalIdLoadAccessImpl(LoadAccessContext context, EntityMappingType entityDescriptor) {
this.context = context; this.context = context;
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
@ -54,6 +60,28 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
return lockOptions; return lockOptions;
} }
public Object enableFetchProfile(String profileName) {
if ( enabledFetchProfiles == null ) {
enabledFetchProfiles = new HashSet<>();
}
enabledFetchProfiles.add( profileName );
if ( disabledFetchProfiles != null ) {
disabledFetchProfiles.remove( profileName );
}
return this;
}
public Object disableFetchProfile(String profileName) {
if ( disabledFetchProfiles == null ) {
disabledFetchProfiles = new HashSet<>();
}
disabledFetchProfiles.add( profileName );
if ( enabledFetchProfiles != null ) {
enabledFetchProfiles.remove( profileName );
}
return this;
}
public boolean isSynchronizationEnabled() { public boolean isSynchronizationEnabled() {
return synchronizationEnabled; return synchronizationEnabled;
} }
@ -100,7 +128,9 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
} }
final PersistenceContext persistenceContext = context.getSession().getPersistenceContextInternal(); final PersistenceContext persistenceContext = context.getSession().getPersistenceContextInternal();
final Collection<?> cachedPkResolutions = persistenceContext.getNaturalIdResolutions().getCachedPkResolutions( entityPersister() ); final Collection<?> cachedPkResolutions =
persistenceContext.getNaturalIdResolutions()
.getCachedPkResolutions( entityPersister() );
for ( Object pk : cachedPkResolutions ) { for ( Object pk : cachedPkResolutions ) {
final EntityKey entityKey = context.getSession().generateEntityKey( pk, entityPersister() ); final EntityKey entityKey = context.getSession().generateEntityKey( pk, entityPersister() );
final Object entity = persistenceContext.getEntity( entityKey ); final Object entity = persistenceContext.getEntity( entityKey );
@ -126,11 +156,7 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
continue; continue;
} }
persistenceContext.getNaturalIdResolutions().handleSynchronization( persistenceContext.getNaturalIdResolutions().handleSynchronization( pk, entity, entityPersister() );
pk,
entity,
entityPersister()
);
} }
} }
@ -144,34 +170,32 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
final SessionImplementor session = context.getSession(); final SessionImplementor session = context.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final Object cachedResolution = persistenceContext.getNaturalIdResolutions().findCachedIdByNaturalId( final Object cachedResolution =
normalizedNaturalIdValue, persistenceContext.getNaturalIdResolutions()
entityPersister() .findCachedIdByNaturalId( normalizedNaturalIdValue, entityPersister() );
);
if ( cachedResolution == INVALID_NATURAL_ID_REFERENCE ) { if ( cachedResolution == INVALID_NATURAL_ID_REFERENCE ) {
// the entity is deleted, although not yet flushed - return null // the entity is deleted, although not yet flushed - return null
return null; return null;
} }
else {
if ( cachedResolution != null ) { if ( cachedResolution != null ) {
return (T) getIdentifierLoadAccess().getReference( cachedResolution ); return (T) getIdentifierLoadAccess().getReference( cachedResolution );
} }
else {
LoaderLogging.LOADER_LOGGER.debugf( LoaderLogging.LOADER_LOGGER.debugf(
"Selecting entity identifier by natural-id for `#getReference` handling - %s : %s", "Selecting entity identifier by natural-id for `#getReference` handling - %s : %s",
entityPersister().getEntityName(), entityPersister().getEntityName(),
normalizedNaturalIdValue normalizedNaturalIdValue
); );
final Object idFromDatabase =
final Object idFromDatabase = entityPersister().getNaturalIdLoader().resolveNaturalIdToId( normalizedNaturalIdValue, session ); entityPersister().getNaturalIdLoader()
if ( idFromDatabase != null ) { .resolveNaturalIdToId( normalizedNaturalIdValue, session );
return (T) getIdentifierLoadAccess().getReference( idFromDatabase ); return idFromDatabase == null ? null : (T) getIdentifierLoadAccess().getReference( idFromDatabase );
} }
}
return null;
} }
@SuppressWarnings("unchecked")
protected final T doLoad(Object normalizedNaturalIdValue) { protected final T doLoad(Object normalizedNaturalIdValue) {
performAnyNeededCrossReferenceSynchronizations(); performAnyNeededCrossReferenceSynchronizations();
@ -181,53 +205,45 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
final SessionImplementor session = context.getSession(); final SessionImplementor session = context.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final Object cachedResolution = persistenceContext.getNaturalIdResolutions().findCachedIdByNaturalId( final Object cachedResolution =
normalizedNaturalIdValue, persistenceContext.getNaturalIdResolutions()
entityPersister() .findCachedIdByNaturalId( normalizedNaturalIdValue, entityPersister() );
);
if ( cachedResolution == INVALID_NATURAL_ID_REFERENCE ) { if ( cachedResolution == INVALID_NATURAL_ID_REFERENCE ) {
return null; return null;
} }
else {
final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers();
final HashSet<String> fetchProfiles =
influencers.adjustFetchProfiles( disabledFetchProfiles, enabledFetchProfiles );
try { try {
final T loaded; final T loaded = cachedResolution != null
? (T) getIdentifierLoadAccess().load(cachedResolution)
if ( cachedResolution != null ) { : (T) entityPersister().getNaturalIdLoader().load( normalizedNaturalIdValue, this, session );
loaded = (T) getIdentifierLoadAccess().load( cachedResolution );
}
else {
loaded = (T) entityPersister().getNaturalIdLoader().load( normalizedNaturalIdValue, this, session );
}
if ( loaded != null ) { if ( loaded != null ) {
final EntityEntry entry;
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( loaded ); final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( loaded );
if ( lazyInitializer != null ) { final EntityEntry entry = lazyInitializer != null
entry = persistenceContext.getEntry( lazyInitializer.getImplementation() ); ? persistenceContext.getEntry( lazyInitializer.getImplementation() )
} : persistenceContext.getEntry( loaded );
else {
entry = persistenceContext.getEntry( loaded );
}
assert entry != null; assert entry != null;
if ( entry.getStatus() == Status.DELETED ) { if ( entry.getStatus() == Status.DELETED ) {
return null; return null;
} }
} }
return loaded; return loaded;
} }
finally { finally {
context.delayedAfterCompletion(); context.delayedAfterCompletion();
influencers.setEnabledFetchProfileNames( fetchProfiles );
}
} }
} }
protected final IdentifierLoadAccess<?> getIdentifierLoadAccess() { protected final IdentifierLoadAccess<?> getIdentifierLoadAccess() {
final IdentifierLoadAccessImpl<?> identifierLoadAccess = new IdentifierLoadAccessImpl<>( context, entityPersister() ); final IdentifierLoadAccessImpl<?> loadAccess = new IdentifierLoadAccessImpl<>( context, entityPersister() );
if ( this.lockOptions != null ) { if ( lockOptions != null ) {
identifierLoadAccess.with( lockOptions ); loadAccess.with( lockOptions );
} }
return identifierLoadAccess; return loadAccess;
} }
protected LoadAccessContext getContext() { protected LoadAccessContext getContext() {

View File

@ -6,7 +6,9 @@
*/ */
package org.hibernate.loader.internal; package org.hibernate.loader.internal;
import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
@ -17,6 +19,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInter
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
import org.hibernate.engine.spi.EffectiveEntityGraph; import org.hibernate.engine.spi.EffectiveEntityGraph;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
@ -46,6 +49,8 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
private Boolean readOnly; private Boolean readOnly;
private RootGraphImplementor<T> rootGraph; private RootGraphImplementor<T> rootGraph;
private GraphSemantic graphSemantic; private GraphSemantic graphSemantic;
private Set<String> enabledFetchProfiles;
private Set<String> disabledFetchProfiles;
public IdentifierLoadAccessImpl(LoadAccessContext context, EntityPersister entityPersister) { public IdentifierLoadAccessImpl(LoadAccessContext context, EntityPersister entityPersister) {
this.context = context; this.context = context;
@ -97,6 +102,9 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
} }
try { try {
final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers();
final HashSet<String> fetchProfiles =
influencers.adjustFetchProfiles( disabledFetchProfiles, enabledFetchProfiles );
final EffectiveEntityGraph effectiveEntityGraph = final EffectiveEntityGraph effectiveEntityGraph =
session.getLoadQueryInfluencers().getEffectiveEntityGraph(); session.getLoadQueryInfluencers().getEffectiveEntityGraph();
if ( graphSemantic != null ) { if ( graphSemantic != null ) {
@ -113,6 +121,7 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
if ( graphSemantic != null ) { if ( graphSemantic != null ) {
effectiveEntityGraph.clear(); effectiveEntityGraph.clear();
} }
influencers.setEnabledFetchProfileNames( fetchProfiles );
} }
} }
finally { finally {
@ -267,4 +276,28 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
public TypeConfiguration getTypeConfiguration() { public TypeConfiguration getTypeConfiguration() {
return context.getSession().getSessionFactory().getTypeConfiguration(); return context.getSession().getSessionFactory().getTypeConfiguration();
} }
@Override
public IdentifierLoadAccess<T> enableFetchProfile(String profileName) {
if ( enabledFetchProfiles == null ) {
enabledFetchProfiles = new HashSet<>();
}
enabledFetchProfiles.add( profileName );
if ( disabledFetchProfiles != null ) {
disabledFetchProfiles.remove( profileName );
}
return this;
}
@Override
public IdentifierLoadAccess<T> disableFetchProfile(String profileName) {
if ( disabledFetchProfiles == null ) {
disabledFetchProfiles = new HashSet<>();
}
disabledFetchProfiles.add( profileName );
if ( enabledFetchProfiles != null ) {
enabledFetchProfiles.remove( profileName );
}
return this;
}
} }

View File

@ -75,4 +75,16 @@ public class NaturalIdLoadAccessImpl<T> extends BaseNaturalIdLoadAccessImpl<T> i
public Optional<T> loadOptional() { public Optional<T> loadOptional() {
return Optional.ofNullable( load() ); return Optional.ofNullable( load() );
} }
@Override
public NaturalIdLoadAccess<T> enableFetchProfile(String profileName) {
super.enableFetchProfile( profileName );
return this;
}
@Override
public NaturalIdLoadAccess<T> disableFetchProfile(String profileName) {
super.enableFetchProfile( profileName );
return this;
}
} }

View File

@ -108,4 +108,17 @@ public class SimpleNaturalIdLoadAccessImpl<T>
public Optional<T> loadOptional(Object naturalIdValue) { public Optional<T> loadOptional(Object naturalIdValue) {
return Optional.ofNullable( load( naturalIdValue ) ); return Optional.ofNullable( load( naturalIdValue ) );
} }
@Override
public SimpleNaturalIdLoadAccess<T> enableFetchProfile(String profileName) {
super.enableFetchProfile( profileName );
return this;
}
@Override
public SimpleNaturalIdLoadAccess<T> disableFetchProfile(String profileName) {
super.enableFetchProfile( profileName );
return this;
}
} }

View File

@ -11,6 +11,7 @@ import java.time.Instant;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -631,7 +632,7 @@ public abstract class AbstractQuery<R>
@Override @Override
public int executeUpdate() throws HibernateException { public int executeUpdate() throws HibernateException {
getSession().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" ); getSession().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" );
beforeQuery(); final HashSet<String> fetchProfiles = beforeQuery();
boolean success = false; boolean success = false;
try { try {
final int result = doExecuteUpdate(); final int result = doExecuteUpdate();
@ -648,7 +649,7 @@ public abstract class AbstractQuery<R>
throw getSession().getExceptionConverter().convert( e ); throw getSession().getExceptionConverter().convert( e );
} }
finally { finally {
afterQuery( success ); afterQuery( success, fetchProfiles );
} }
} }

View File

@ -15,7 +15,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.Spliterators; import java.util.Spliterators;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -41,7 +40,6 @@ import org.hibernate.LockOptions;
import org.hibernate.NonUniqueResultException; import org.hibernate.NonUniqueResultException;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
import org.hibernate.TypeMismatchException; import org.hibernate.TypeMismatchException;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.GraphSemantic; import org.hibernate.graph.GraphSemantic;
@ -419,11 +417,10 @@ public abstract class AbstractSelectionQuery<R>
private FlushMode sessionFlushMode; private FlushMode sessionFlushMode;
private CacheMode sessionCacheMode; private CacheMode sessionCacheMode;
private HashSet<String> fetchProfiles;
@Override @Override
public List<R> list() { public List<R> list() {
beforeQuery(); final HashSet<String> fetchProfiles = beforeQuery();
boolean success = false; boolean success = false;
try { try {
final List<R> result = doList(); final List<R> result = doList();
@ -440,16 +437,17 @@ public abstract class AbstractSelectionQuery<R>
throw getSession().getExceptionConverter().convert( he, getQueryOptions().getLockOptions() ); throw getSession().getExceptionConverter().convert( he, getQueryOptions().getLockOptions() );
} }
finally { finally {
afterQuery( success ); afterQuery( success, fetchProfiles );
} }
} }
protected void beforeQuery() { protected HashSet<String> beforeQuery() {
getQueryParameterBindings().validate(); getQueryParameterBindings().validate();
getSession().prepareForQueryExecution( final SharedSessionContractImplementor session = getSession();
requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) final MutableQueryOptions options = getQueryOptions();
);
session.prepareForQueryExecution( requiresTxn( options.getLockOptions().findGreatestLockMode() ) );
prepareForExecution(); prepareForExecution();
assert sessionFlushMode == null; assert sessionFlushMode == null;
@ -457,47 +455,33 @@ public abstract class AbstractSelectionQuery<R>
final FlushMode effectiveFlushMode = getHibernateFlushMode(); final FlushMode effectiveFlushMode = getHibernateFlushMode();
if ( effectiveFlushMode != null ) { if ( effectiveFlushMode != null ) {
sessionFlushMode = getSession().getHibernateFlushMode(); sessionFlushMode = session.getHibernateFlushMode();
getSession().setHibernateFlushMode( effectiveFlushMode ); session.setHibernateFlushMode( effectiveFlushMode );
} }
final CacheMode effectiveCacheMode = getCacheMode(); final CacheMode effectiveCacheMode = getCacheMode();
if ( effectiveCacheMode != null ) { if ( effectiveCacheMode != null ) {
sessionCacheMode = getSession().getCacheMode(); sessionCacheMode = session.getCacheMode();
getSession().setCacheMode( effectiveCacheMode ); session.setCacheMode( effectiveCacheMode );
} }
final LoadQueryInfluencers loadQueryInfluencers = getSession().getLoadQueryInfluencers(); return session.getLoadQueryInfluencers()
fetchProfiles = loadQueryInfluencers.hasEnabledFetchProfiles() .adjustFetchProfiles( options.getDisabledFetchProfiles(), options.getEnabledFetchProfiles() );
? new HashSet<>( loadQueryInfluencers.getEnabledFetchProfileNames() )
: null;
final Set<String> disabledFetchProfiles = getQueryOptions().getDisabledFetchProfiles();
if ( disabledFetchProfiles != null ) {
for ( String name: disabledFetchProfiles ) {
loadQueryInfluencers.disableFetchProfile( name );
}
}
final Set<String> enabledFetchProfiles = getQueryOptions().getEnabledFetchProfiles();
if ( enabledFetchProfiles != null ) {
for ( String name: enabledFetchProfiles ) {
loadQueryInfluencers.enableFetchProfile( name );
}
}
} }
protected abstract void prepareForExecution(); protected abstract void prepareForExecution();
protected void afterQuery(boolean success) { protected void afterQuery(boolean success, HashSet<String> fetchProfiles) {
getSession().getLoadQueryInfluencers().setEnabledFetchProfileNames( fetchProfiles ); final SharedSessionContractImplementor session = getSession();
session.getLoadQueryInfluencers().setEnabledFetchProfileNames( fetchProfiles );
afterQuery(); afterQuery();
if ( !getSession().isTransactionInProgress() ) { if ( !session.isTransactionInProgress() ) {
getSession().getJdbcCoordinator().getLogicalConnection().afterTransaction(); session.getJdbcCoordinator().getLogicalConnection().afterTransaction();
} }
getSession().afterOperation( success ); session.afterOperation( success );
} }
protected void afterQuery() { protected void afterQuery() {

View File

@ -14,6 +14,7 @@ import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -668,7 +669,7 @@ public class QuerySqmImpl<R>
public int executeUpdate() { public int executeUpdate() {
verifyUpdate(); verifyUpdate();
getSession().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" ); getSession().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" );
beforeQuery(); final HashSet<String> fetchProfiles = beforeQuery();
boolean success = false; boolean success = false;
try { try {
final int result = doExecuteUpdate(); final int result = doExecuteUpdate();
@ -685,7 +686,7 @@ public class QuerySqmImpl<R>
throw getSession().getExceptionConverter().convert( e ); throw getSession().getExceptionConverter().convert( e );
} }
finally { finally {
afterQuery( success ); afterQuery( success, fetchProfiles );
} }
} }

View File

@ -19,12 +19,18 @@ public interface Dao {
@Find @Find
Book getBook(String title, String author); Book getBook(String title, String author);
@Find(enabledFetchProfiles="Hello")
Book getBookFetching(String title, String author);
@Find @Find
Book getBook(String title, String isbn, String author); Book getBook(String title, String isbn, String author);
@Find @Find
List<Book> getBooks(String title); List<Book> getBooks(String title);
@Find(enabledFetchProfiles="Hello")
List<Book> getBooksFetching(String title);
@Find @Find
SelectionQuery<Book> createBooksSelectionQuery(String title); SelectionQuery<Book> createBooksSelectionQuery(String title);