HHH-16695 add enableFetchProfile() to XxxxIdLoadAccess
This commit is contained in:
parent
2e351831f1
commit
09f110254f
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue