clean up IdentifierLoadAccessImpl

This commit is contained in:
Gavin King 2023-06-03 10:41:40 +02:00
parent 7c089a5c4b
commit f511282ce3
1 changed files with 118 additions and 91 deletions

View File

@ -16,7 +16,8 @@ import org.hibernate.ObjectNotFoundException;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
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.LoadQueryInfluencers; import org.hibernate.engine.spi.EffectiveEntityGraph;
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;
import org.hibernate.event.spi.LoadEvent; import org.hibernate.event.spi.LoadEvent;
@ -24,13 +25,13 @@ import org.hibernate.event.spi.LoadEventListener;
import org.hibernate.graph.GraphSemantic; import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.RootGraph; import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
/** /**
* Standard implementation of load-by-id * Standard implementation of load-by-id
* *
@ -83,8 +84,8 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
protected T perform(Supplier<T> executor) { protected T perform(Supplier<T> executor) {
final SessionImplementor session = context.getSession(); final SessionImplementor session = context.getSession();
final CacheMode sessionCacheMode = session.getCacheMode();
CacheMode sessionCacheMode = session.getCacheMode();
boolean cacheModeChanged = false; boolean cacheModeChanged = false;
if ( cacheMode != null ) { if ( cacheMode != null ) {
// naive check for now... // naive check for now...
@ -96,11 +97,13 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
} }
try { try {
final EffectiveEntityGraph effectiveEntityGraph =
session.getLoadQueryInfluencers().getEffectiveEntityGraph();
if ( graphSemantic != null ) { if ( graphSemantic != null ) {
if ( rootGraph == null ) { if ( rootGraph == null ) {
throw new IllegalArgumentException( "Graph semantic specified, but no RootGraph was supplied" ); throw new IllegalArgumentException( "Graph semantic specified, but no RootGraph was supplied" );
} }
session.getLoadQueryInfluencers().getEffectiveEntityGraph().applyGraph( rootGraph, graphSemantic ); effectiveEntityGraph.applyGraph( rootGraph, graphSemantic );
} }
try { try {
@ -108,7 +111,7 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
} }
finally { finally {
if ( graphSemantic != null ) { if ( graphSemantic != null ) {
session.getLoadQueryInfluencers().getEffectiveEntityGraph().clear(); effectiveEntityGraph.clear();
} }
} }
} }
@ -123,36 +126,21 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
protected T doGetReference(Object id) { protected T doGetReference(Object id) {
final SessionImplementor session = context.getSession(); final SessionImplementor session = context.getSession();
final EventSource eventSource = session.asEventSource(); final SessionFactoryImplementor factory = session.getFactory();
final LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers(); return (T) getReference(
coerceId( id, factory ),
session.asEventSource(),
factory,
entityPersister.getEntityName(),
isReadOnly( session )
);
}
final JpaCompliance jpaCompliance = session.getFactory().getSessionFactoryOptions().getJpaCompliance();
if ( ! jpaCompliance.isLoadByIdComplianceEnabled() ) {
id = entityPersister.getIdentifierMapping().getJavaType().coerce( id, this );
}
String entityName = entityPersister.getEntityName(); private Boolean isReadOnly(SessionImplementor session) {
Boolean readOnly = this.readOnly != null ? this.readOnly : loadQueryInfluencers.getReadOnly(); return readOnly != null
? readOnly
if ( lockOptions != null ) { : session.getLoadQueryInfluencers().getReadOnly();
LoadEvent event = new LoadEvent( id, entityName, lockOptions, eventSource, readOnly );
context.fireLoad( event, LoadEventListener.LOAD );
return (T) event.getResult();
}
LoadEvent event = new LoadEvent( id, entityName, false, eventSource, readOnly );
boolean success = false;
try {
context.fireLoad( event, LoadEventListener.LOAD );
if ( event.getResult() == null ) {
session.getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
}
success = true;
return (T) event.getResult();
}
finally {
context.afterOperation( success );
}
} }
@Override @Override
@ -168,74 +156,113 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
protected final T doLoad(Object id) { protected final T doLoad(Object id) {
final SessionImplementor session = context.getSession(); final SessionImplementor session = context.getSession();
final EventSource eventSource = session.asEventSource(); final Object result = load(
final LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers(); coerceId( id, session.getFactory() ),
session.asEventSource(),
final JpaCompliance jpaCompliance = session.getFactory().getSessionFactoryOptions().getJpaCompliance(); entityPersister.getEntityName(),
if ( ! jpaCompliance.isLoadByIdComplianceEnabled() ) { isReadOnly( session )
try { );
id = entityPersister.getIdentifierMapping().getJavaType().coerce( id, this );
}
catch ( Exception e ) {
throw new IllegalArgumentException( "Argument '" + id
+ "' could not be converted to the identifier type of entity '" + entityPersister.getEntityName() + "'"
+ " [" + e.getMessage() + "]", e );
}
}
String entityName = entityPersister.getEntityName();
Boolean readOnly = this.readOnly != null ? this.readOnly : loadQueryInfluencers.getReadOnly();
if ( lockOptions != null ) {
LoadEvent event = new LoadEvent( id, entityName, lockOptions, eventSource, readOnly );
context.fireLoad( event, LoadEventListener.GET );
final Object result = event.getResult();
initializeIfNecessary( result );
return (T) result;
}
LoadEvent event = new LoadEvent( id, entityName, false, eventSource, readOnly );
boolean success = false;
try {
context.fireLoad( event, LoadEventListener.GET );
success = true;
}
catch (ObjectNotFoundException e) {
// if session cache contains proxy for non-existing object
}
finally {
context.afterOperation( success );
}
final Object result = event.getResult();
initializeIfNecessary( result ); initializeIfNecessary( result );
return (T) result; return (T) result;
} }
private void initializeIfNecessary(Object result) { private Object getReference(
if ( result == null ) { Object id,
return; EventSource eventSource,
} SessionFactoryImplementor factory,
String entityName,
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( result ); Boolean readOnly) {
if ( lazyInitializer != null ) { if ( lockOptions != null ) {
if ( lazyInitializer.isUninitialized() ) { final LoadEvent event = new LoadEvent(id, entityName, lockOptions, eventSource, readOnly);
lazyInitializer.initialize(); context.fireLoad( event, LoadEventListener.LOAD );
} return event.getResult();
} }
else { else {
final BytecodeEnhancementMetadata enhancementMetadata = entityPersister.getEntityMetamodel().getBytecodeEnhancementMetadata(); final LoadEvent event = new LoadEvent( id, entityName, false, eventSource, readOnly );
if ( enhancementMetadata.isEnhancedForLazyLoading() ) { boolean success = false;
final BytecodeLazyAttributeInterceptor interceptor = enhancementMetadata.extractLazyInterceptor( result); try {
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) { context.fireLoad( event, LoadEventListener.LOAD );
( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( result, null ); final Object result = event.getResult();
if ( result == null ) {
factory.getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
}
success = true;
return result;
}
finally {
context.afterOperation( success );
}
}
}
private Object load(Object id, EventSource eventSource, String entityName, Boolean readOnly) {
final LoadEvent event;
if ( lockOptions != null ) {
event = new LoadEvent( id, entityName, lockOptions, eventSource, readOnly );
context.fireLoad( event, LoadEventListener.GET );
}
else {
event = new LoadEvent( id, entityName, false, eventSource, readOnly );
boolean success = false;
try {
context.fireLoad( event, LoadEventListener.GET );
success = true;
}
catch (ObjectNotFoundException e) {
// if session cache contains proxy for non-existing object
}
finally {
context.afterOperation( success );
}
}
return event.getResult();
}
private Object coerceId(Object id, SessionFactoryImplementor factory) {
if ( isLoadByIdComplianceEnabled( factory ) ) {
return id;
}
else {
try {
return entityPersister.getIdentifierMapping().getJavaType().coerce( id, this );
}
catch ( Exception e ) {
throw new IllegalArgumentException( "Argument '" + id
+ "' could not be converted to the identifier type of entity '"
+ entityPersister.getEntityName() + "'"
+ " [" + e.getMessage() + "]", e );
}
}
}
private void initializeIfNecessary(Object result) {
if ( result != null ) {
final LazyInitializer lazyInitializer = extractLazyInitializer( result );
if ( lazyInitializer != null ) {
if ( lazyInitializer.isUninitialized() ) {
lazyInitializer.initialize();
}
}
else {
final BytecodeEnhancementMetadata enhancementMetadata =
entityPersister.getEntityMetamodel().getBytecodeEnhancementMetadata();
if ( enhancementMetadata.isEnhancedForLazyLoading() ) {
final BytecodeLazyAttributeInterceptor interceptor =
enhancementMetadata.extractLazyInterceptor( result);
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
final EnhancementAsProxyLazinessInterceptor lazinessInterceptor =
(EnhancementAsProxyLazinessInterceptor) interceptor;
lazinessInterceptor.forceInitialize( result, null );
}
} }
} }
} }
} }
private static boolean isLoadByIdComplianceEnabled(SessionFactoryImplementor factory) {
return factory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled();
}
@Override @Override
public TypeConfiguration getTypeConfiguration() { public TypeConfiguration getTypeConfiguration() {
return context.getSession().getSessionFactory().getTypeConfiguration(); return context.getSession().getSessionFactory().getTypeConfiguration();