mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-10 13:14:50 +00:00
HHH-16468 Don't create fetch for _identifierMapper anymore
This commit is contained in:
parent
5a3d60f508
commit
3ee817008a
@ -689,7 +689,7 @@ private BiConsumer<Fetchable, Boolean> createFetchableBiConsumer(
|
||||
LoaderSqlAstCreationState creationState,
|
||||
ImmutableFetchList.Builder fetches) {
|
||||
return (fetchable, isKeyFetchable) -> {
|
||||
if ( !fetchable.isSelectable() ) {
|
||||
if ( !fetchable.isSelectable() || fetchable.getPartName().equals( NavigablePath.IDENTIFIER_MAPPER_PROPERTY ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
@ -35,8 +36,15 @@
|
||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.NonAggregatedIdentifierMappingFetch;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.NonAggregatedIdentifierMappingResult;
|
||||
|
||||
/**
|
||||
* A "non-aggregated" composite identifier.
|
||||
@ -316,6 +324,38 @@ public void applySqlSelections(
|
||||
identifierValueMapper.applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new NonAggregatedIdentifierMappingResult<>(
|
||||
navigablePath,
|
||||
this,
|
||||
resultVariable,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new NonAggregatedIdentifierMappingFetch(
|
||||
fetchablePath,
|
||||
this,
|
||||
fetchParent,
|
||||
fetchTiming,
|
||||
selected,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// EmbeddableValuedFetchable
|
||||
|
||||
|
@ -459,7 +459,7 @@ public ImmutableFetchList visitFetches(FetchParent fetchParent) {
|
||||
|
||||
private Consumer<Fetchable> createFetchableConsumer(FetchParent fetchParent, ImmutableFetchList.Builder fetches) {
|
||||
return fetchable -> {
|
||||
if ( !fetchable.isSelectable() ) {
|
||||
if ( !fetchable.isSelectable() || fetchable.getPartName().equals( NavigablePath.IDENTIFIER_MAPPER_PROPERTY ) ) {
|
||||
return;
|
||||
}
|
||||
final String fetchableName = fetchable.getFetchableName();
|
||||
|
@ -7144,7 +7144,7 @@ public Fetch visitIdentifierFetch(EntityResultGraphNode fetchParent) {
|
||||
}
|
||||
|
||||
private Fetch createFetch(FetchParent fetchParent, Fetchable fetchable, Boolean isKeyFetchable) {
|
||||
if ( !fetchable.isSelectable() ) {
|
||||
if ( !fetchable.isSelectable() || fetchable.getPartName().equals( NavigablePath.IDENTIFIER_MAPPER_PROPERTY ) ) {
|
||||
return null;
|
||||
}
|
||||
final NavigablePath resolvedNavigablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||
|
@ -9,17 +9,12 @@
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.internal.StandardEmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.VirtualModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.ValueAccess;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
@ -37,41 +32,27 @@
|
||||
import org.hibernate.sql.results.internal.NullValueAssembler;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||
import static org.hibernate.sql.results.graph.entity.internal.BatchEntityInsideEmbeddableSelectFetchInitializer.BATCH_PROPERTY;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentAccess implements EmbeddableInitializer,
|
||||
ValueAccess {
|
||||
private static final Object NULL_MARKER = new Object() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Composite NULL_MARKER";
|
||||
}
|
||||
};
|
||||
public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentAccess
|
||||
implements EmbeddableInitializer, ValueAccess {
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
private final EmbeddableValuedModelPart embedded;
|
||||
private final EmbeddableMappingType representationEmbeddable;
|
||||
private final EmbeddableRepresentationStrategy representationStrategy;
|
||||
private final FetchParentAccess fetchParentAccess;
|
||||
private final boolean createEmptyCompositesEnabled;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private final List<DomainResultAssembler<?>> assemblers;
|
||||
|
||||
private final boolean usesStandardInstantiation;
|
||||
|
||||
// per-row state
|
||||
private final Object[] rowState;
|
||||
private Boolean stateAllNull;
|
||||
private Boolean stateInjected;
|
||||
private State state = State.INITIAL;
|
||||
protected Object compositeInstance;
|
||||
private boolean isParentInitialized;
|
||||
private RowProcessingState wrappedProcessingState;
|
||||
|
||||
public AbstractEmbeddableInitializer(
|
||||
@ -83,16 +64,6 @@ public AbstractEmbeddableInitializer(
|
||||
this.fetchParentAccess = fetchParentAccess;
|
||||
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embedded.getEmbeddableTypeDescriptor();
|
||||
if ( embedded instanceof CompositeIdentifierMapping ) {
|
||||
representationEmbeddable = ( (CompositeIdentifierMapping) embedded ).getMappedIdEmbeddableTypeDescriptor();
|
||||
}
|
||||
else {
|
||||
representationEmbeddable = embeddableTypeDescriptor;
|
||||
}
|
||||
|
||||
this.representationStrategy = representationEmbeddable.getRepresentationStrategy();
|
||||
this.usesStandardInstantiation = representationStrategy.getInstantiator() instanceof StandardEmbeddableInstantiator;
|
||||
|
||||
final int size = embeddableTypeDescriptor.getNumberOfFetchables();
|
||||
this.rowState = new Object[ size ];
|
||||
this.assemblers = arrayList( size );
|
||||
@ -140,7 +111,7 @@ public NavigablePath getNavigablePath() {
|
||||
|
||||
@Override
|
||||
public Object getCompositeInstance() {
|
||||
return compositeInstance == NULL_MARKER ? null : compositeInstance;
|
||||
return state == State.NULL ? null : compositeInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -174,16 +145,6 @@ public void resolveInstance(RowProcessingState processingState) {
|
||||
public void initializeInstance(RowProcessingState processingState) {
|
||||
EmbeddableLoadingLogger.EMBEDDED_LOAD_LOGGER.debugf( "Initializing composite instance [%s]", navigablePath );
|
||||
|
||||
if ( compositeInstance == NULL_MARKER ) {
|
||||
// we already know it is null
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isParentInstanceNull() ) {
|
||||
compositeInstance = NULL_MARKER;
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT: This method might be called multiple times for the same role for a single row.
|
||||
// EmbeddableAssembler calls it as part of its `#assemble` and the RowReader calls it
|
||||
// as part of its normal Initializer handling
|
||||
@ -203,13 +164,12 @@ public void initializeInstance(RowProcessingState processingState) {
|
||||
// critical in the case we have custom constructor injection. Luckily, custom instantiation
|
||||
// is only allowed for non-key usage atm, so we leverage that distinction here
|
||||
|
||||
if ( !usesStandardInstantiation ) {
|
||||
// we have a custom instantiator
|
||||
if ( compositeInstance != null ) {
|
||||
switch ( state ) {
|
||||
case NULL:
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( isParentInitialized ) {
|
||||
case INITIAL:
|
||||
if ( isParentInstanceNull() ) {
|
||||
state = State.NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -217,22 +177,15 @@ public void initializeInstance(RowProcessingState processingState) {
|
||||
if ( wrappedProcessingState == null ) {
|
||||
wrappedProcessingState = wrapProcessingState( processingState );
|
||||
}
|
||||
initializeInstance( );
|
||||
}
|
||||
|
||||
private void initializeInstance() {
|
||||
stateInjected = false;
|
||||
extractRowState( wrappedProcessingState );
|
||||
prepareCompositeInstance( wrappedProcessingState );
|
||||
if ( isParentInitialized ) {
|
||||
if ( state == State.NULL ) {
|
||||
return;
|
||||
}
|
||||
if ( !stateInjected ) {
|
||||
handleParentInjection( wrappedProcessingState );
|
||||
}
|
||||
|
||||
if ( compositeInstance != NULL_MARKER ) {
|
||||
notifyResolutionListeners( compositeInstance );
|
||||
case EXTRACTED:
|
||||
if ( embedded.getParentInjectionAttributePropertyAccess() != null || embedded instanceof VirtualModelPart ) {
|
||||
handleParentInjection( wrappedProcessingState );
|
||||
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( compositeInstance );
|
||||
// If the composite instance has a lazy initializer attached, this means that the embeddable is actually virtual
|
||||
@ -241,8 +194,8 @@ private void initializeInstance() {
|
||||
final Initializer parentInitializer = wrappedProcessingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInitializer != this ) {
|
||||
( (FetchParentAccess) parentInitializer ).registerResolutionListener( (entity) -> {
|
||||
representationEmbeddable.setValues( entity, rowState );
|
||||
stateInjected = true;
|
||||
embedded.getEmbeddableTypeDescriptor().setValues( entity, rowState );
|
||||
state = State.INJECTED;
|
||||
} );
|
||||
}
|
||||
else {
|
||||
@ -252,25 +205,25 @@ private void initializeInstance() {
|
||||
// NOTE: `valuesAccess` is set to null to indicate that all values are null,
|
||||
// as opposed to returning the all-null value array. the instantiator
|
||||
// interprets that as the values are not known or were all null.
|
||||
final Object target = representationStrategy
|
||||
final Object target = embedded.getEmbeddableTypeDescriptor().getRepresentationStrategy()
|
||||
.getInstantiator()
|
||||
.instantiate( this, sessionFactory);
|
||||
stateInjected = true;
|
||||
state = State.INJECTED;
|
||||
lazyInitializer.setImplementation( target );
|
||||
}
|
||||
}
|
||||
else if ( stateAllNull == FALSE && stateInjected != TRUE ) {
|
||||
representationEmbeddable.setValues( compositeInstance, rowState );
|
||||
stateInjected = true;
|
||||
else {
|
||||
embedded.getEmbeddableTypeDescriptor().setValues( compositeInstance, rowState );
|
||||
state = State.INJECTED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
state = State.INJECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareCompositeInstance(RowProcessingState processingState) {
|
||||
if ( compositeInstance != null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Virtual model parts use the owning entity as container which the fetch parent access provides.
|
||||
// For an identifier or foreign key this is called during the resolveKey phase of the fetch parent,
|
||||
// so we can't use the fetch parent access in that case.
|
||||
@ -282,7 +235,6 @@ private void prepareCompositeInstance(RowProcessingState processingState) {
|
||||
compositeInstance = fetchParentAccess.getInitializedInstance();
|
||||
EntityInitializer entityInitializer = fetchParentAccess.asEntityInitializer();
|
||||
if ( entityInitializer != null && entityInitializer.isEntityInitialized() ) {
|
||||
this.isParentInitialized = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -290,7 +242,6 @@ private void prepareCompositeInstance(RowProcessingState processingState) {
|
||||
if ( compositeInstance == null ) {
|
||||
compositeInstance = createCompositeInstance(
|
||||
navigablePath,
|
||||
representationStrategy,
|
||||
sessionFactory
|
||||
);
|
||||
}
|
||||
@ -326,7 +277,7 @@ private boolean isParentInstanceNull() {
|
||||
}
|
||||
|
||||
private void extractRowState(RowProcessingState processingState) {
|
||||
stateAllNull = true;
|
||||
boolean stateAllNull = true;
|
||||
final boolean isKey = ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getLocalName() )
|
||||
|| EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() );
|
||||
@ -353,51 +304,23 @@ else if ( isKey ) {
|
||||
}
|
||||
}
|
||||
|
||||
applyMapsId( processingState );
|
||||
state = stateAllNull ? State.NULL : State.EXTRACTED;
|
||||
}
|
||||
|
||||
private void applyMapsId(RowProcessingState processingState) {
|
||||
final SharedSessionContractImplementor session = processingState.getSession();
|
||||
if ( embedded instanceof CompositeIdentifierMapping ) {
|
||||
final CompositeIdentifierMapping cid = (CompositeIdentifierMapping) embedded;
|
||||
final EmbeddableMappingType mappedIdEmbeddable = cid.getMappedIdEmbeddableTypeDescriptor();
|
||||
if ( cid.hasContainingClass() ) {
|
||||
final EmbeddableMappingType virtualIdEmbeddable = embedded.getEmbeddableTypeDescriptor();
|
||||
if ( virtualIdEmbeddable == mappedIdEmbeddable ) {
|
||||
return;
|
||||
}
|
||||
|
||||
virtualIdEmbeddable.forEachAttributeMapping(
|
||||
(position, virtualIdAttribute) -> {
|
||||
final AttributeMapping mappedIdAttribute = mappedIdEmbeddable.getAttributeMapping( position );
|
||||
|
||||
if ( virtualIdAttribute instanceof ToOneAttributeMapping
|
||||
&& !( mappedIdAttribute instanceof ToOneAttributeMapping ) ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) virtualIdAttribute;
|
||||
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
|
||||
final Object associationKey = fkDescriptor.getAssociationKeyFromSide(
|
||||
rowState[position],
|
||||
toOneAttributeMapping.getSideNature().inverse(),
|
||||
session
|
||||
);
|
||||
rowState[position] = associationKey;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
private Object createCompositeInstance(NavigablePath navigablePath, SessionFactoryImplementor sessionFactory) {
|
||||
if ( state == State.NULL ) {
|
||||
// todo (6.0) : should we initialize the composite instance if it has a parent attribute?
|
||||
// if ( !createEmptyCompositesEnabled && embedded.getParentInjectionAttributePropertyAccess() == null ) {
|
||||
if ( !createEmptyCompositesEnabled ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Object createCompositeInstance(
|
||||
NavigablePath navigablePath,
|
||||
EmbeddableRepresentationStrategy representationStrategy,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
if ( !createEmptyCompositesEnabled && stateAllNull == TRUE ) {
|
||||
return NULL_MARKER;
|
||||
}
|
||||
|
||||
final Object instance = representationStrategy.getInstantiator().instantiate( this, sessionFactory );
|
||||
stateInjected = true;
|
||||
final Object instance = embedded.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator()
|
||||
.instantiate( this, sessionFactory );
|
||||
state = State.EXTRACTED;
|
||||
|
||||
EmbeddableLoadingLogger.EMBEDDED_LOAD_LOGGER.debugf( "Created composite instance [%s] : %s", navigablePath, instance );
|
||||
|
||||
@ -406,12 +329,12 @@ private Object createCompositeInstance(
|
||||
|
||||
@Override
|
||||
public Object[] getValues() {
|
||||
return stateAllNull ? null : rowState;
|
||||
return state == State.NULL ? null : rowState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getValue(int i, Class<T> clazz) {
|
||||
return stateAllNull ? null : clazz.cast( rowState[i] );
|
||||
return state == State.NULL ? null : clazz.cast( rowState[i] );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -420,17 +343,6 @@ public Object getOwner() {
|
||||
}
|
||||
|
||||
private void handleParentInjection(RowProcessingState processingState) {
|
||||
// todo (6.0) : should we initialize the composite instance if we get here and it is null (not NULL_MARKER)?
|
||||
|
||||
// we want to avoid injection for `NULL_MARKER`
|
||||
if ( compositeInstance == null || compositeInstance == NULL_MARKER ) {
|
||||
EmbeddableLoadingLogger.EMBEDDED_LOAD_LOGGER.debugf(
|
||||
"Skipping parent injection for null embeddable [%s]",
|
||||
navigablePath
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final PropertyAccess parentInjectionAccess = embedded.getParentInjectionAttributePropertyAccess();
|
||||
if ( parentInjectionAccess == null ) {
|
||||
// embeddable defined no parent injection
|
||||
@ -504,9 +416,7 @@ private Object determineParentInstance(RowProcessingState processingState) {
|
||||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
compositeInstance = null;
|
||||
stateAllNull = null;
|
||||
stateInjected = null;
|
||||
isParentInitialized = false;
|
||||
state = State.INITIAL;
|
||||
wrappedProcessingState = null;
|
||||
|
||||
clearResolutionListeners();
|
||||
@ -516,4 +426,10 @@ public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "(" + navigablePath + ") : `" + getInitializedPart().getJavaType().getJavaTypeClass() + "`";
|
||||
}
|
||||
enum State {
|
||||
INITIAL,
|
||||
EXTRACTED,
|
||||
NULL,
|
||||
INJECTED
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.ValueAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableLoadingLogger;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||
import org.hibernate.sql.results.internal.NullValueAssembler;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||
import static org.hibernate.sql.results.graph.entity.internal.BatchEntityInsideEmbeddableSelectFetchInitializer.BATCH_PROPERTY;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractNonAggregatedIdentifierMappingInitializer extends AbstractFetchParentAccess
|
||||
implements EmbeddableInitializer, ValueAccess {
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
private final NonAggregatedIdentifierMapping embedded;
|
||||
private final EmbeddableMappingType representationEmbeddable;
|
||||
private final EmbeddableRepresentationStrategy representationStrategy;
|
||||
private final FetchParentAccess fetchParentAccess;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private final List<DomainResultAssembler<?>> assemblers;
|
||||
private final boolean hasIdClass;
|
||||
|
||||
|
||||
// per-row state
|
||||
private final Object[] virtualIdState;
|
||||
private final Object[] idClassState;
|
||||
private State state = State.INITIAL;
|
||||
protected Object compositeInstance;
|
||||
|
||||
public AbstractNonAggregatedIdentifierMappingInitializer(
|
||||
EmbeddableResultGraphNode resultDescriptor,
|
||||
FetchParentAccess fetchParentAccess,
|
||||
AssemblerCreationState creationState) {
|
||||
this.navigablePath = resultDescriptor.getNavigablePath();
|
||||
this.embedded = (NonAggregatedIdentifierMapping) resultDescriptor.getReferencedMappingContainer();
|
||||
this.fetchParentAccess = fetchParentAccess;
|
||||
|
||||
final EmbeddableMappingType virtualIdEmbeddable = embedded.getEmbeddableTypeDescriptor();
|
||||
this.representationEmbeddable = embedded.getMappedIdEmbeddableTypeDescriptor();
|
||||
this.representationStrategy = representationEmbeddable.getRepresentationStrategy();
|
||||
this.hasIdClass = embedded.hasContainingClass() && virtualIdEmbeddable != representationEmbeddable;
|
||||
|
||||
final int size = virtualIdEmbeddable.getNumberOfFetchables();
|
||||
this.virtualIdState = new Object[ size ];
|
||||
this.idClassState = new Object[ size ];
|
||||
this.assemblers = arrayList( size );
|
||||
|
||||
this.sessionFactory = creationState.getSqlAstCreationContext().getSessionFactory();
|
||||
initializeAssemblers( resultDescriptor, creationState, virtualIdEmbeddable );
|
||||
}
|
||||
|
||||
|
||||
protected void initializeAssemblers(
|
||||
EmbeddableResultGraphNode resultDescriptor,
|
||||
AssemblerCreationState creationState,
|
||||
EmbeddableMappingType embeddableTypeDescriptor) {
|
||||
final int size = embeddableTypeDescriptor.getNumberOfFetchables();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final Fetchable stateArrayContributor = embeddableTypeDescriptor.getFetchable( i );
|
||||
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
|
||||
|
||||
final DomainResultAssembler<?> stateAssembler = fetch == null
|
||||
? new NullValueAssembler<>( stateArrayContributor.getJavaType() )
|
||||
: fetch.createAssembler( this, creationState );
|
||||
|
||||
assemblers.add( stateAssembler );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getInitializedPart() {
|
||||
return embedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchParentAccess getFetchParentAccess() {
|
||||
return fetchParentAccess;
|
||||
}
|
||||
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompositeInstance() {
|
||||
return compositeInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchParentAccess findFirstEntityDescriptorAccess() {
|
||||
if ( fetchParentAccess == null ) {
|
||||
return null;
|
||||
}
|
||||
return fetchParentAccess.findFirstEntityDescriptorAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInitializer findFirstEntityInitializer() {
|
||||
final FetchParentAccess firstEntityDescriptorAccess = findFirstEntityDescriptorAccess();
|
||||
if ( firstEntityDescriptorAccess == null ) {
|
||||
return null;
|
||||
}
|
||||
return firstEntityDescriptorAccess.findFirstEntityInitializer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState processingState) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState processingState) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState processingState) {
|
||||
EmbeddableLoadingLogger.EMBEDDED_LOAD_LOGGER.debugf( "Initializing composite instance [%s]", navigablePath );
|
||||
|
||||
switch ( state ) {
|
||||
case NULL:
|
||||
return;
|
||||
case INITIAL:
|
||||
// If we don't have an id class and this is a find by id lookup, we just use that instance
|
||||
if ( !hasIdClass && processingState.getEntityId() != null
|
||||
&& navigablePath.getParent().getParent() == null
|
||||
&& navigablePath instanceof EntityIdentifierNavigablePath ) {
|
||||
compositeInstance = processingState.getEntityId();
|
||||
state = State.INJECTED;
|
||||
return;
|
||||
}
|
||||
// We need to possibly wrap the processing state if the embeddable is within an aggregate
|
||||
processingState = wrapProcessingState( processingState );
|
||||
extractRowState( processingState );
|
||||
if ( state == State.NULL ) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
compositeInstance = representationStrategy.getInstantiator().instantiate( this, sessionFactory );
|
||||
}
|
||||
case EXTRACTED:
|
||||
final Object parentInstance;
|
||||
if ( fetchParentAccess != null && ( parentInstance = fetchParentAccess.getInitializedInstance() ) != null ) {
|
||||
notifyResolutionListeners( compositeInstance );
|
||||
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( parentInstance );
|
||||
// If the composite instance has a lazy initializer attached, this means that the embeddable is actually virtual
|
||||
// and the compositeInstance == entity, so we have to inject the row state into the entity when it finishes resolution
|
||||
if ( lazyInitializer != null ) {
|
||||
final Initializer parentInitializer = processingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInitializer != this ) {
|
||||
( (FetchParentAccess) parentInitializer ).registerResolutionListener( (entity) -> {
|
||||
embedded.getVirtualIdEmbeddable().setValues( entity, virtualIdState );
|
||||
state = State.INJECTED;
|
||||
} );
|
||||
}
|
||||
else {
|
||||
assert false;
|
||||
// At this point, createEmptyCompositesEnabled is always true, so we generate
|
||||
// the composite instance.
|
||||
//
|
||||
// NOTE: `valuesAccess` is set to null to indicate that all values are null,
|
||||
// as opposed to returning the all-null value array. the instantiator
|
||||
// interprets that as the values are not known or were all null.
|
||||
final Object target = representationStrategy
|
||||
.getInstantiator()
|
||||
.instantiate( this, sessionFactory);
|
||||
|
||||
state = State.INJECTED;
|
||||
lazyInitializer.setImplementation( target );
|
||||
}
|
||||
}
|
||||
else {
|
||||
embedded.getVirtualIdEmbeddable().setValues( parentInstance, virtualIdState );
|
||||
state = State.INJECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void extractRowState(RowProcessingState processingState) {
|
||||
state = State.NULL;
|
||||
for ( int i = 0; i < assemblers.size(); i++ ) {
|
||||
final DomainResultAssembler<?> assembler = assemblers.get( i );
|
||||
final Object contributorValue = assembler.assemble(
|
||||
processingState,
|
||||
processingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
|
||||
);
|
||||
|
||||
if ( contributorValue == null ) {
|
||||
// This is a key and there is a null part, the whole thing has to be turned into null
|
||||
return;
|
||||
}
|
||||
if ( contributorValue == BATCH_PROPERTY ) {
|
||||
virtualIdState[i] = null;
|
||||
idClassState[i] = null;
|
||||
}
|
||||
else {
|
||||
virtualIdState[i] = contributorValue;
|
||||
idClassState[i] = contributorValue;
|
||||
if ( hasIdClass ) {
|
||||
final AttributeMapping virtualIdAttribute = embedded.getEmbeddableTypeDescriptor().getAttributeMapping( i );
|
||||
final AttributeMapping mappedIdAttribute = representationEmbeddable.getAttributeMapping( i );
|
||||
if ( virtualIdAttribute instanceof ToOneAttributeMapping
|
||||
&& !( mappedIdAttribute instanceof ToOneAttributeMapping ) ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) virtualIdAttribute;
|
||||
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
|
||||
final Object associationKey = fkDescriptor.getAssociationKeyFromSide(
|
||||
virtualIdState[i],
|
||||
toOneAttributeMapping.getSideNature().inverse(),
|
||||
processingState.getSession()
|
||||
);
|
||||
idClassState[i] = associationKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
state = State.EXTRACTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getValues() {
|
||||
return state == State.NULL ? null : idClassState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getValue(int i, Class<T> clazz) {
|
||||
return state == State.NULL ? null : clazz.cast( idClassState[i] );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOwner() {
|
||||
return fetchParentAccess.getInitializedInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
compositeInstance = null;
|
||||
state = State.INITIAL;
|
||||
|
||||
clearResolutionListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "(" + navigablePath + ") : `" + getInitializedPart().getJavaType().getJavaTypeClass() + "`";
|
||||
}
|
||||
|
||||
enum State {
|
||||
INITIAL,
|
||||
EXTRACTED,
|
||||
NULL,
|
||||
INJECTED
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParent;
|
||||
@ -98,7 +99,9 @@ public DomainResultAssembler<T> createResultAssembler(
|
||||
final EmbeddableInitializer initializer = creationState.resolveInitializer(
|
||||
getNavigablePath(),
|
||||
getReferencedModePart(),
|
||||
() -> new EmbeddableResultInitializer( this, parentAccess, creationState )
|
||||
() -> getReferencedModePart() instanceof NonAggregatedIdentifierMapping
|
||||
? new NonAggregatedIdentifierMappingResultInitializer( this, null, creationState )
|
||||
: new EmbeddableResultInitializer( this, null, creationState )
|
||||
).asEmbeddableInitializer();
|
||||
|
||||
assert initializer != null;
|
||||
|
@ -6,13 +6,17 @@
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.engine.spi.CollectionKey;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.exec.internal.BaseExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.Callback;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.sql.results.spi.RowReader;
|
||||
@ -89,8 +93,43 @@ public QueryParameterBindings getQueryParameterBindings() {
|
||||
return processingState.getQueryParameterBindings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScrollResult(){
|
||||
return processingState.isScrollResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callback getCallback() {
|
||||
return processingState.getCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionKey getCollectionKey() {
|
||||
return processingState.getCollectionKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityInstance() {
|
||||
return processingState.getEntityInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityId() {
|
||||
return processingState.getEntityId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLoadingEntityEntry(EntityKey entityKey, LoadingEntityEntry entry) {
|
||||
processingState.registerLoadingEntityEntry( entityKey, entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterStatement(LogicalConnectionImplementor logicalConnection) {
|
||||
processingState.afterStatement( logicalConnection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasQueryExecutionToBeAddedToStatistics() {
|
||||
return processingState.hasQueryExecutionToBeAddedToStatistics();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||
|
||||
public class NonAggregatedIdentifierMappingFetch extends EmbeddableFetchImpl {
|
||||
public NonAggregatedIdentifierMappingFetch(
|
||||
NavigablePath navigablePath,
|
||||
NonAggregatedIdentifierMapping embeddedPartDescriptor,
|
||||
FetchParent fetchParent,
|
||||
FetchTiming fetchTiming,
|
||||
boolean hasTableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
super( navigablePath, embeddedPartDescriptor, fetchParent, fetchTiming, hasTableGroup, creationState );
|
||||
}
|
||||
|
||||
public NonAggregatedIdentifierMappingFetch(EmbeddableFetchImpl original) {
|
||||
super( original );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Initializer buildEmbeddableFetchInitializer(
|
||||
FetchParentAccess parentAccess,
|
||||
EmbeddableResultGraphNode embeddableFetch,
|
||||
AssemblerCreationState creationState) {
|
||||
return new NonAggregatedIdentifierMappingFetchInitializer( parentAccess, this, creationState );
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.embeddable.AbstractEmbeddableInitializer;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NonAggregatedIdentifierMappingFetchInitializer
|
||||
extends AbstractNonAggregatedIdentifierMappingInitializer {
|
||||
public NonAggregatedIdentifierMappingFetchInitializer(
|
||||
FetchParentAccess fetchParentAccess,
|
||||
EmbeddableResultGraphNode resultDescriptor,
|
||||
AssemblerCreationState creationState) {
|
||||
super( resultDescriptor, fetchParentAccess, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getParentKey() {
|
||||
return findFirstEntityDescriptorAccess().getParentKey();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
|
||||
|
||||
public class NonAggregatedIdentifierMappingResult<T> extends EmbeddableResultImpl<T> {
|
||||
public NonAggregatedIdentifierMappingResult(
|
||||
NavigablePath navigablePath,
|
||||
NonAggregatedIdentifierMapping modelPart,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
super( navigablePath, modelPart, resultVariable, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler<T> createResultAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
AssemblerCreationState creationState) {
|
||||
final EmbeddableInitializer initializer = creationState.resolveInitializer(
|
||||
getNavigablePath().append( "{embeddable_result}" ),
|
||||
getReferencedModePart(),
|
||||
() -> new NonAggregatedIdentifierMappingResultInitializer(
|
||||
this,
|
||||
parentAccess,
|
||||
creationState
|
||||
)
|
||||
).asEmbeddableInitializer();
|
||||
|
||||
assert initializer != null;
|
||||
|
||||
//noinspection unchecked
|
||||
return new EmbeddableAssembler( initializer );
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NonAggregatedIdentifierMappingResultInitializer extends AbstractNonAggregatedIdentifierMappingInitializer {
|
||||
public NonAggregatedIdentifierMappingResultInitializer(
|
||||
EmbeddableResultGraphNode resultDescriptor,
|
||||
FetchParentAccess parentAccess,
|
||||
AssemblerCreationState creationState) {
|
||||
super( resultDescriptor, parentAccess, creationState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getParentKey() {
|
||||
return findFirstEntityDescriptorAccess().getParentKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EmbeddableResultInitializer(" + getNavigablePath() + ")";
|
||||
}
|
||||
}
|
@ -52,6 +52,7 @@
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResultAssembler;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableAssembler;
|
||||
import org.hibernate.sql.results.internal.NullValueAssembler;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
|
||||
@ -524,6 +525,13 @@ else if ( entityInstanceFromExecutionContext != null ) {
|
||||
// look to see if another initializer from a parent load context or an earlier
|
||||
// initializer is already loading the entity
|
||||
entityInstance = resolveInstance( entityIdentifier, existingLoadingEntry, rowProcessingState );
|
||||
if ( isOwningInitializer && !isInitialized && identifierAssembler instanceof EmbeddableAssembler ) {
|
||||
// If this is the owning initializer and the returned object is not initialized,
|
||||
// this means that the entity instance was just instantiated.
|
||||
// In this case, we want to call "assemble" and hence "initializeInstance" on the initializer
|
||||
// for possibly non-aggregated identifier mappings, so inject the virtual id representation
|
||||
identifierAssembler.assemble( rowProcessingState );
|
||||
}
|
||||
}
|
||||
|
||||
upgradeLockMode( rowProcessingState );
|
||||
|
@ -7,6 +7,8 @@
|
||||
package org.hibernate.sql.results.internal;
|
||||
|
||||
import org.hibernate.engine.spi.CollectionKey;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
@ -15,6 +17,7 @@
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||
import org.hibernate.sql.results.jdbc.internal.JdbcValuesCacheHit;
|
||||
import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValues;
|
||||
@ -138,6 +141,11 @@ public QueryParameterBindings getQueryParameterBindings() {
|
||||
return getJdbcValuesSourceProcessingState().getExecutionContext().getQueryParameterBindings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScrollResult(){
|
||||
return executionContext.isScrollResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callback getCallback() {
|
||||
return executionContext.getCallback();
|
||||
@ -148,6 +156,31 @@ public CollectionKey getCollectionKey() {
|
||||
return executionContext.getCollectionKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityInstance() {
|
||||
return executionContext.getEntityInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityId() {
|
||||
return executionContext.getEntityId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLoadingEntityEntry(EntityKey entityKey, LoadingEntityEntry entry) {
|
||||
executionContext.registerLoadingEntityEntry( entityKey, entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterStatement(LogicalConnectionImplementor logicalConnection) {
|
||||
executionContext.afterStatement( logicalConnection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasQueryExecutionToBeAddedToStatistics() {
|
||||
return executionContext.hasQueryExecutionToBeAddedToStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Initializer resolveInitializer(NavigablePath path) {
|
||||
return this.initializers.resolveInitializer( path );
|
||||
|
Loading…
x
Reference in New Issue
Block a user