Implemented SelectEagerCollectionInitializer
This commit is contained in:
parent
2fa3889e5a
commit
6462218587
|
@ -73,12 +73,8 @@ public abstract class AbstractBagSemantics<B extends Collection<?>> implements C
|
|||
String resultVariable,
|
||||
LockMode lockMode,
|
||||
DomainResultCreationState creationState) {
|
||||
final TableGroup tableGroup = creationState.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( navigablePath );
|
||||
return new BagInitializerProducer(
|
||||
attributeMapping,
|
||||
selected,
|
||||
attributeMapping.getIdentifierDescriptor() == null ? null : attributeMapping.getIdentifierDescriptor().generateFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( CollectionPart.Nature.ID.getName() ),
|
||||
|
|
|
@ -86,12 +86,8 @@ public abstract class AbstractMapSemantics<M extends Map<?,?>> implements MapSem
|
|||
String resultVariable,
|
||||
LockMode lockMode,
|
||||
DomainResultCreationState creationState) {
|
||||
final TableGroup tableGroup = creationState.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( navigablePath );
|
||||
return new MapInitializerProducer(
|
||||
attributeMapping,
|
||||
selected,
|
||||
attributeMapping.getIndexDescriptor().generateFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( CollectionPart.Nature.INDEX.getName() ),
|
||||
|
|
|
@ -58,7 +58,6 @@ public abstract class AbstractSetSemantics<S extends Set<?>> implements Collecti
|
|||
DomainResultCreationState creationState) {
|
||||
return new SetInitializerProducer(
|
||||
attributeMapping,
|
||||
selected,
|
||||
attributeMapping.getElementDescriptor().generateFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( CollectionPart.Nature.ELEMENT.getName() ),
|
||||
|
|
|
@ -133,6 +133,7 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
|
|||
public void initializeEmptyCollection(CollectionPersister persister) {
|
||||
assert array == null;
|
||||
array = Array.newInstance( persister.getElementClass(), 0 );
|
||||
persister.getAttributeMapping().getPropertyAccess().getSetter().set( getOwner(), array, getSession().getFactory() );
|
||||
endRead();
|
||||
}
|
||||
|
||||
|
|
|
@ -104,12 +104,8 @@ public class StandardArraySemantics implements CollectionSemantics<Object[]> {
|
|||
String resultVariable,
|
||||
LockMode lockMode,
|
||||
DomainResultCreationState creationState) {
|
||||
final TableGroup tableGroup = creationState.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( navigablePath );
|
||||
return new ArrayInitializerProducer(
|
||||
attributeMapping,
|
||||
selected,
|
||||
attributeMapping.getIndexDescriptor().generateFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( CollectionPart.Nature.INDEX.getName() ),
|
||||
|
|
|
@ -78,12 +78,8 @@ public class StandardListSemantics implements CollectionSemantics<List> {
|
|||
String resultVariable,
|
||||
LockMode lockMode,
|
||||
DomainResultCreationState creationState) {
|
||||
final TableGroup tableGroup = creationState.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( navigablePath );
|
||||
return new ListInitializerProducer(
|
||||
attributeMapping,
|
||||
selected,
|
||||
attributeMapping.getIndexDescriptor().generateFetch(
|
||||
fetchParent,
|
||||
navigablePath.append( CollectionPart.Nature.INDEX.getName() ),
|
||||
|
|
|
@ -90,7 +90,8 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
private void handlePotentiallyEmptyCollection(
|
||||
PersistentCollection collection,
|
||||
SessionImplementor source,
|
||||
CollectionEntry ce, CollectionPersister ceLoadedPersister) {
|
||||
CollectionEntry ce,
|
||||
CollectionPersister ceLoadedPersister) {
|
||||
if ( !collection.wasInitialized() ) {
|
||||
collection.initializeEmptyCollection( ceLoadedPersister );
|
||||
org.hibernate.sql.results.internal.Helper.finalizeCollectionLoading(
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.hibernate.sql.results.graph.FetchParent;
|
|||
import org.hibernate.sql.results.graph.collection.internal.CollectionDomainResult;
|
||||
import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch;
|
||||
import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch;
|
||||
import org.hibernate.sql.results.graph.collection.internal.SelectEagerCollectionFetch;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.ForeignKeyDirection;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -364,45 +365,55 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
|||
DomainResultCreationState creationState) {
|
||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||
|
||||
if ( fetchTiming == FetchTiming.IMMEDIATE || selected || getCollectionDescriptor().getCollectionType().hasHolder() ) {
|
||||
final TableGroup collectionTableGroup = sqlAstCreationState.getFromClauseAccess().resolveTableGroup(
|
||||
fetchablePath,
|
||||
p -> {
|
||||
final TableGroup lhsTableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( fetchParent.getNavigablePath() );
|
||||
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
|
||||
fetchablePath,
|
||||
lhsTableGroup,
|
||||
null,
|
||||
SqlAstJoinType.LEFT,
|
||||
lockMode,
|
||||
creationState.getSqlAliasBaseManager(),
|
||||
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||
creationState.getSqlAstCreationState().getCreationContext()
|
||||
);
|
||||
if ( fetchTiming == FetchTiming.IMMEDIATE) {
|
||||
if ( selected ) {
|
||||
final TableGroup collectionTableGroup = sqlAstCreationState.getFromClauseAccess().resolveTableGroup(
|
||||
fetchablePath,
|
||||
p -> {
|
||||
final TableGroup lhsTableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup(
|
||||
fetchParent.getNavigablePath() );
|
||||
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
|
||||
fetchablePath,
|
||||
lhsTableGroup,
|
||||
null,
|
||||
SqlAstJoinType.LEFT,
|
||||
lockMode,
|
||||
creationState.getSqlAliasBaseManager(),
|
||||
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||
creationState.getSqlAstCreationState().getCreationContext()
|
||||
);
|
||||
|
||||
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
||||
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
||||
|
||||
sqlAstCreationState.getFromClauseAccess().registerTableGroup( fetchablePath, tableGroupJoin.getJoinedGroup() );
|
||||
sqlAstCreationState.getFromClauseAccess().registerTableGroup(
|
||||
fetchablePath,
|
||||
tableGroupJoin.getJoinedGroup()
|
||||
);
|
||||
|
||||
return tableGroupJoin.getJoinedGroup();
|
||||
}
|
||||
);
|
||||
return tableGroupJoin.getJoinedGroup();
|
||||
}
|
||||
);
|
||||
|
||||
return new EagerCollectionFetch(
|
||||
fetchablePath,
|
||||
this,
|
||||
collectionTableGroup,
|
||||
getAttributeMetadataAccess().resolveAttributeMetadata( null ).isNullable(),
|
||||
fetchParent,
|
||||
creationState
|
||||
);
|
||||
return new EagerCollectionFetch(
|
||||
fetchablePath,
|
||||
this,
|
||||
collectionTableGroup,
|
||||
fetchParent,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new SelectEagerCollectionFetch( fetchablePath, this, fetchParent );
|
||||
}
|
||||
}
|
||||
|
||||
if ( getCollectionDescriptor().getCollectionType().hasHolder() ) {
|
||||
return new SelectEagerCollectionFetch( fetchablePath, this, fetchParent );
|
||||
}
|
||||
|
||||
return new DelayedCollectionFetch(
|
||||
fetchablePath,
|
||||
this,
|
||||
true,
|
||||
fetchParent
|
||||
);
|
||||
}
|
||||
|
|
|
@ -56,11 +56,6 @@ public interface Fetch extends DomainResultGraphNode {
|
|||
*/
|
||||
boolean hasTableGroup();
|
||||
|
||||
/**
|
||||
* Is this fetch nullable? Meaning is it mapped as being optional?
|
||||
*/
|
||||
boolean isNullable();
|
||||
|
||||
/**
|
||||
* Create the assembler for this fetch
|
||||
*/
|
||||
|
|
|
@ -92,11 +92,6 @@ public class BasicFetch<T> implements Fetch, BasicResultGraphNode<T> {
|
|||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.collection.internal;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentArrayHolder;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public abstract class AbstractCollectionAssembler implements DomainResultAssembler {
|
||||
private final PluralAttributeMapping fetchedMapping;
|
||||
|
||||
protected final CollectionInitializer initializer;
|
||||
|
||||
public AbstractCollectionAssembler(
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
CollectionInitializer initializer) {
|
||||
this.fetchedMapping = fetchedMapping;
|
||||
this.initializer = initializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
PersistentCollection collectionInstance = initializer.getCollectionInstance();
|
||||
if ( collectionInstance instanceof PersistentArrayHolder ) {
|
||||
return collectionInstance.getValue();
|
||||
}
|
||||
return collectionInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getAssembledJavaTypeDescriptor() {
|
||||
return fetchedMapping.getJavaTypeDescriptor();
|
||||
}
|
||||
}
|
|
@ -6,16 +6,11 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.collection.internal;
|
||||
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionKey;
|
||||
import org.hibernate.internal.log.LoggingHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
|
@ -26,42 +21,44 @@ import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
|||
*/
|
||||
public abstract class AbstractCollectionInitializer implements CollectionInitializer {
|
||||
private final NavigablePath collectionPath;
|
||||
private final PluralAttributeMapping collectionAttributeMapping;
|
||||
protected final PluralAttributeMapping collectionAttributeMapping;
|
||||
|
||||
private final FetchParentAccess parentAccess;
|
||||
protected final FetchParentAccess parentAccess;
|
||||
|
||||
private final boolean selected;
|
||||
|
||||
/**
|
||||
* refers to the collection's container value - which collection-key?
|
||||
*/
|
||||
private final DomainResultAssembler keyContainerAssembler;
|
||||
|
||||
/**
|
||||
* refers to the rows entry in the collection. null indicates that the collection is empty
|
||||
*/
|
||||
private final DomainResultAssembler keyCollectionAssembler;
|
||||
|
||||
// per-row state
|
||||
private Object keyContainerValue;
|
||||
private Object keyCollectionValue;
|
||||
|
||||
private CollectionKey collectionKey;
|
||||
protected PersistentCollection collectionInstance;
|
||||
protected CollectionKey collectionKey;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected AbstractCollectionInitializer(
|
||||
NavigablePath collectionPath,
|
||||
PluralAttributeMapping collectionAttributeMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler) {
|
||||
FetchParentAccess parentAccess) {
|
||||
this.collectionPath = collectionPath;
|
||||
this.collectionAttributeMapping = collectionAttributeMapping;
|
||||
this.parentAccess = parentAccess;
|
||||
this.selected = selected;
|
||||
this.keyContainerAssembler = keyContainerAssembler;
|
||||
this.keyCollectionAssembler = keyCollectionAssembler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if ( collectionKey != null ) {
|
||||
// already resolved
|
||||
return;
|
||||
}
|
||||
|
||||
final Object parentKey = parentAccess.getParentKey();
|
||||
if ( parentKey != null ) {
|
||||
collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
parentKey
|
||||
);
|
||||
|
||||
parentAccess.registerResolutionListener( owner -> collectionInstance.setOwner( owner ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentCollection getCollectionInstance() {
|
||||
return collectionInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,119 +75,18 @@ public abstract class AbstractCollectionInitializer implements CollectionInitial
|
|||
return getCollectionAttributeMapping();
|
||||
}
|
||||
|
||||
/**
|
||||
* Are the values for performing this initialization present in the current
|
||||
* {@link JdbcValuesSourceProcessingState}?
|
||||
* Or should a separate/subsequent select be performed
|
||||
*
|
||||
* todo (6.0) : opportunity for performance gain by batching these selects triggered at the end of processing the JdbcValuesSource
|
||||
*/
|
||||
protected boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
protected FetchParentAccess getParentAccess() {
|
||||
return parentAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the container/owner side of the collection key (FK). Identifies the
|
||||
* owner of the collection
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Object getKeyContainerValue() {
|
||||
return keyContainerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the collection side of the collection key (FK). Identifies
|
||||
* inclusion in the collection. Can be null to indicate that the current row
|
||||
* does not contain any collection values
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Object getKeyCollectionValue() {
|
||||
return keyCollectionValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionKey resolveCollectionKey(RowProcessingState rowProcessingState) {
|
||||
resolveKey( rowProcessingState );
|
||||
return collectionKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if ( collectionKey != null ) {
|
||||
// already resolved
|
||||
return;
|
||||
}
|
||||
|
||||
final CollectionKey loadingKey = rowProcessingState.getCollectionKey();
|
||||
if ( loadingKey != null ) {
|
||||
collectionKey = loadingKey;
|
||||
return;
|
||||
}
|
||||
|
||||
final JdbcValuesSourceProcessingOptions processingOptions = rowProcessingState.getJdbcValuesSourceProcessingState()
|
||||
.getProcessingOptions();
|
||||
|
||||
keyContainerValue = keyContainerAssembler.assemble(
|
||||
rowProcessingState,
|
||||
processingOptions
|
||||
);
|
||||
|
||||
if ( keyCollectionAssembler == null || keyContainerAssembler == keyCollectionAssembler ) {
|
||||
keyCollectionValue = keyContainerValue;
|
||||
}
|
||||
else {
|
||||
keyCollectionValue = keyCollectionAssembler.assemble(
|
||||
rowProcessingState,
|
||||
processingOptions
|
||||
);
|
||||
}
|
||||
|
||||
Object keyContainerValue = getKeyContainerValue();
|
||||
if ( keyContainerValue != null ) {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyContainerValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
StringHelper.collapse( this.getClass().getName() ),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( keyCollectionValue != null ) {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyCollectionValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
StringHelper.collapse( this.getClass().getName() ),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
parentAccess.getParentKey()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
keyContainerValue = null;
|
||||
keyCollectionValue = null;
|
||||
|
||||
collectionKey = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.sql.results.graph.FetchParentAccess;
|
|||
import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger;
|
||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
||||
import org.hibernate.sql.results.internal.LoadingCollectionEntryImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
/**
|
||||
|
@ -40,52 +41,42 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
private final LockMode lockMode;
|
||||
|
||||
// per-row state
|
||||
private PersistentCollection collectionInstance;
|
||||
private LoadingCollectionEntryImpl responsibility;
|
||||
private boolean responsible;
|
||||
|
||||
/**
|
||||
* refers to the collection's container value - which collection-key?
|
||||
*/
|
||||
private final DomainResultAssembler keyContainerAssembler;
|
||||
|
||||
/**
|
||||
* refers to the rows entry in the collection. null indicates that the collection is empty
|
||||
*/
|
||||
private final DomainResultAssembler keyCollectionAssembler;
|
||||
|
||||
|
||||
// per-row state
|
||||
private Object keyContainerValue;
|
||||
private Object keyCollectionValue;
|
||||
|
||||
public AbstractImmediateCollectionInitializer(
|
||||
NavigablePath collectionPath,
|
||||
PluralAttributeMapping collectionAttributeMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler) {
|
||||
super( collectionPath, collectionAttributeMapping, parentAccess, selected, keyContainerAssembler, keyCollectionAssembler );
|
||||
super( collectionPath, collectionAttributeMapping, parentAccess );
|
||||
this.keyContainerAssembler = keyContainerAssembler;
|
||||
this.keyCollectionAssembler = keyCollectionAssembler;
|
||||
this.lockMode = lockMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentCollection getCollectionInstance() {
|
||||
return collectionInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
if ( collectionInstance != null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PluralAttributeMapping collectionAttributeMapping = getCollectionAttributeMapping();
|
||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
||||
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
|
||||
final CollectionKey collectionKey = resolveCollectionKey( rowProcessingState );
|
||||
|
||||
if ( collectionKey == null ) {
|
||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||
null,
|
||||
collectionDescriptor,
|
||||
session
|
||||
);
|
||||
collectionInstance.initializeEmptyCollection( collectionDescriptor );
|
||||
persistenceContext.addNonLazyCollection( collectionInstance );
|
||||
}
|
||||
|
||||
if ( CollectionLoadingLogger.TRACE_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.tracef(
|
||||
"(%s) Beginning Initializer#resolveInstance for collection : %s",
|
||||
|
@ -99,6 +90,8 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// First, look for a LoadingCollectionEntry
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
|
||||
final LoadingCollectionEntry existingLoadingEntry = persistenceContext
|
||||
.getLoadContexts()
|
||||
|
@ -159,7 +152,6 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
return;
|
||||
}
|
||||
else {
|
||||
assert isSelected();
|
||||
takeResponsibility( rowProcessingState, collectionKey );
|
||||
}
|
||||
}
|
||||
|
@ -185,25 +177,16 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
return;
|
||||
}
|
||||
else {
|
||||
assert isSelected();
|
||||
takeResponsibility( rowProcessingState, collectionKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isSelected() ) {
|
||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||
collectionKey.getKey(),
|
||||
collectionDescriptor,
|
||||
session
|
||||
);
|
||||
persistenceContext.addNonLazyCollection( collectionInstance );
|
||||
|
||||
// EARLY EXIT!!!
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final PluralAttributeMapping collectionAttributeMapping = getCollectionAttributeMapping();
|
||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
||||
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||
|
||||
if ( collectionInstance == null && collectionKey != null ) {
|
||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||
collectionKey.getKey(),
|
||||
|
@ -240,10 +223,6 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
owner -> collectionInstance.setOwner( owner )
|
||||
);
|
||||
}
|
||||
|
||||
// if ( getCollectionDescriptor().getSemantics().getCollectionClassification() == CollectionClassification.ARRAY ) {
|
||||
// persistenceContext.addCollectionHolder( collectionInstance );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,6 +239,93 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if ( collectionKey != null ) {
|
||||
// already resolved
|
||||
return;
|
||||
}
|
||||
|
||||
final CollectionKey loadingKey = rowProcessingState.getCollectionKey();
|
||||
if ( loadingKey != null ) {
|
||||
collectionKey = loadingKey;
|
||||
return;
|
||||
}
|
||||
|
||||
final JdbcValuesSourceProcessingOptions processingOptions = rowProcessingState.getJdbcValuesSourceProcessingState()
|
||||
.getProcessingOptions();
|
||||
|
||||
keyContainerValue = keyContainerAssembler.assemble(
|
||||
rowProcessingState,
|
||||
processingOptions
|
||||
);
|
||||
|
||||
if ( keyCollectionAssembler == null || keyContainerAssembler == keyCollectionAssembler ) {
|
||||
keyCollectionValue = keyContainerValue;
|
||||
}
|
||||
else {
|
||||
keyCollectionValue = keyCollectionAssembler.assemble(
|
||||
rowProcessingState,
|
||||
processingOptions
|
||||
);
|
||||
}
|
||||
|
||||
Object keyContainerValue = getKeyContainerValue();
|
||||
if ( keyContainerValue != null ) {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyContainerValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
StringHelper.collapse( this.getClass().getName() ),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( keyCollectionValue != null ) {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyCollectionValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
StringHelper.collapse( this.getClass().getName() ),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
parentAccess.getParentKey()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the container/owner side of the collection key (FK). Identifies the
|
||||
* owner of the collection
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Object getKeyContainerValue() {
|
||||
return keyContainerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the collection side of the collection key (FK). Identifies
|
||||
* inclusion in the collection. Can be null to indicate that the current row
|
||||
* does not contain any collection values
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Object getKeyCollectionValue() {
|
||||
return keyCollectionValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
if ( responsibility == null ) {
|
||||
|
@ -295,6 +361,8 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
super.finishUpRow( rowProcessingState );
|
||||
|
||||
keyContainerValue = null;
|
||||
keyCollectionValue = null;
|
||||
collectionInstance = null;
|
||||
responsibility = null;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ public class ArrayInitializer extends AbstractImmediateCollectionInitializer {
|
|||
NavigablePath navigablePath,
|
||||
PluralAttributeMapping arrayDescriptor,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler,
|
||||
|
@ -41,7 +40,6 @@ public class ArrayInitializer extends AbstractImmediateCollectionInitializer {
|
|||
navigablePath,
|
||||
arrayDescriptor,
|
||||
parentAccess,
|
||||
selected,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler
|
||||
|
|
|
@ -24,17 +24,14 @@ import org.hibernate.sql.results.graph.Initializer;
|
|||
*/
|
||||
public class ArrayInitializerProducer implements CollectionInitializerProducer {
|
||||
private final PluralAttributeMapping arrayDescriptor;
|
||||
private final boolean joined;
|
||||
private final Fetch listIndexFetch;
|
||||
private final Fetch elementFetch;
|
||||
|
||||
public ArrayInitializerProducer(
|
||||
PluralAttributeMapping arrayDescriptor,
|
||||
boolean joined,
|
||||
Fetch listIndexFetch,
|
||||
Fetch elementFetch) {
|
||||
this.arrayDescriptor = arrayDescriptor;
|
||||
this.joined = joined;
|
||||
this.listIndexFetch = listIndexFetch;
|
||||
this.elementFetch = elementFetch;
|
||||
}
|
||||
|
@ -53,7 +50,6 @@ public class ArrayInitializerProducer implements CollectionInitializerProducer {
|
|||
navigablePath,
|
||||
arrayDescriptor,
|
||||
parentAccess,
|
||||
joined,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler,
|
||||
|
|
|
@ -33,13 +33,12 @@ public class BagInitializer extends AbstractImmediateCollectionInitializer {
|
|||
PluralAttributeMapping bagDescriptor,
|
||||
FetchParentAccess parentAccess,
|
||||
NavigablePath navigablePath,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler,
|
||||
DomainResultAssembler elementAssembler,
|
||||
DomainResultAssembler collectionIdAssembler) {
|
||||
super( navigablePath, bagDescriptor, parentAccess, selected, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
super( navigablePath, bagDescriptor, parentAccess, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
this.elementAssembler = elementAssembler;
|
||||
this.collectionIdAssembler = collectionIdAssembler;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,14 @@ import org.hibernate.sql.results.graph.Initializer;
|
|||
*/
|
||||
public class BagInitializerProducer implements CollectionInitializerProducer {
|
||||
private final PluralAttributeMapping bagDescriptor;
|
||||
private final boolean selected;
|
||||
private final Fetch collectionIdFetch;
|
||||
private final Fetch elementFetch;
|
||||
|
||||
public BagInitializerProducer(
|
||||
PluralAttributeMapping bagDescriptor,
|
||||
boolean selected,
|
||||
Fetch collectionIdFetch,
|
||||
Fetch elementFetch) {
|
||||
this.bagDescriptor = bagDescriptor;
|
||||
this.selected = selected;
|
||||
|
||||
if ( bagDescriptor.getIdentifierDescriptor() != null ) {
|
||||
assert collectionIdFetch != null;
|
||||
|
@ -82,7 +79,6 @@ public class BagInitializerProducer implements CollectionInitializerProducer {
|
|||
bagDescriptor,
|
||||
parentAccess,
|
||||
navigablePath,
|
||||
selected,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler,
|
||||
|
|
|
@ -18,19 +18,15 @@ public abstract class CollectionFetch implements Fetch {
|
|||
private final NavigablePath fetchedPath;
|
||||
private final PluralAttributeMapping fetchedAttribute;
|
||||
|
||||
private final boolean nullable;
|
||||
|
||||
private final FetchParent fetchParent;
|
||||
|
||||
public CollectionFetch(
|
||||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedAttribute,
|
||||
boolean nullable,
|
||||
FetchParent fetchParent) {
|
||||
this.fetchedPath = fetchedPath;
|
||||
this.fetchedAttribute = fetchedAttribute;
|
||||
this.fetchParent = fetchParent;
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,9 +43,4 @@ public abstract class CollectionFetch implements Fetch {
|
|||
public NavigablePath getNavigablePath() {
|
||||
return fetchedPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,50 +8,23 @@ package org.hibernate.sql.results.graph.collection.internal;
|
|||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentArrayHolder;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DelayedCollectionAssembler implements DomainResultAssembler {
|
||||
private final PluralAttributeMapping fetchedMapping;
|
||||
|
||||
private final CollectionInitializer initializer;
|
||||
|
||||
public class DelayedCollectionAssembler extends AbstractCollectionAssembler {
|
||||
public DelayedCollectionAssembler(
|
||||
NavigablePath fetchPath,
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
Consumer<Initializer> collector,
|
||||
AssemblerCreationState creationState) {
|
||||
this.fetchedMapping = fetchedMapping;
|
||||
this.initializer = new DelayedCollectionInitializer( fetchPath, fetchedMapping, parentAccess );
|
||||
super( fetchedMapping, new DelayedCollectionInitializer( fetchPath, fetchedMapping, parentAccess ) );
|
||||
collector.accept( initializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
PersistentCollection collectionInstance = initializer.getCollectionInstance();
|
||||
if ( collectionInstance instanceof PersistentArrayHolder ) {
|
||||
return collectionInstance.getValue();
|
||||
}
|
||||
return collectionInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getAssembledJavaTypeDescriptor() {
|
||||
return fetchedMapping.getJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@ public class DelayedCollectionFetch extends CollectionFetch {
|
|||
public DelayedCollectionFetch(
|
||||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedAttribute,
|
||||
boolean nullable,
|
||||
FetchParent fetchParent) {
|
||||
super( fetchedPath, fetchedAttribute, nullable, fetchParent );
|
||||
super( fetchedPath, fetchedAttribute, fetchParent );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,94 +8,35 @@ package org.hibernate.sql.results.graph.collection.internal;
|
|||
|
||||
import org.hibernate.collection.spi.CollectionSemantics;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.log.LoggingHelper;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DelayedCollectionInitializer implements CollectionInitializer {
|
||||
|
||||
private final NavigablePath fetchedPath;
|
||||
private final PluralAttributeMapping fetchedMapping;
|
||||
private final FetchParentAccess parentAccess;
|
||||
|
||||
private CollectionKey collectionKey;
|
||||
private PersistentCollection collectionInstance;
|
||||
public class DelayedCollectionInitializer extends AbstractCollectionInitializer {
|
||||
|
||||
public DelayedCollectionInitializer(
|
||||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
FetchParentAccess parentAccess) {
|
||||
this.fetchedPath = fetchedPath;
|
||||
this.fetchedMapping = fetchedMapping;
|
||||
this.parentAccess = parentAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return fetchedPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if ( collectionKey != null ) {
|
||||
// already resolved
|
||||
return;
|
||||
}
|
||||
|
||||
final Object parentKey = parentAccess.getParentKey();
|
||||
if ( parentKey != null ) {
|
||||
collectionKey = new CollectionKey(
|
||||
fetchedMapping.getCollectionDescriptor(),
|
||||
parentKey
|
||||
);
|
||||
|
||||
parentAccess.registerResolutionListener( owner -> collectionInstance.setOwner( owner ) );
|
||||
}
|
||||
super( fetchedPath, fetchedMapping, parentAccess );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
if ( collectionKey != null ) {
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
|
||||
if ( collectionKey != null ) {
|
||||
EntityInitializer entityInitializer = getEntityInitializer( rowProcessingState );
|
||||
|
||||
|
||||
final Object entityUsingInterceptor = persistenceContext.getEntity( entityInitializer.getEntityKey() );
|
||||
if ( entityUsingInterceptor != null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Object key = collectionKey.getKey();
|
||||
|
||||
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
||||
.findLoadingCollectionEntry( collectionKey );
|
||||
final PersistentCollection registeredInstance = persistenceContext.getCollection( collectionKey );
|
||||
final Object key = collectionKey.getKey();
|
||||
|
||||
if ( loadingEntry != null ) {
|
||||
instance = loadingEntry.getCollectionInstance();
|
||||
return;
|
||||
}
|
||||
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
||||
.findLoadingCollectionEntry( collectionKey );
|
||||
|
||||
|
@ -104,9 +45,6 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( registeredInstance != null ) {
|
||||
instance = registeredInstance;
|
||||
return;
|
||||
final PersistentCollection existing = persistenceContext.getCollection( collectionKey );
|
||||
|
||||
if ( existing != null ) {
|
||||
|
@ -114,38 +52,12 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
|
|||
return;
|
||||
}
|
||||
|
||||
instance = makePersistentCollection( fetchedMapping, key, rowProcessingState );
|
||||
|
||||
persistenceContext.addUninitializedCollection(
|
||||
getInitializingCollectionDescriptor(),
|
||||
instance,
|
||||
key
|
||||
);
|
||||
}
|
||||
else {
|
||||
instance = makePersistentCollection( fetchedMapping, collectionKey, rowProcessingState );
|
||||
instance.initializeEmptyCollection( getInitializingCollectionDescriptor() );
|
||||
persistenceContext.addNonLazyCollection( instance );
|
||||
}
|
||||
}
|
||||
|
||||
private static PersistentCollection makePersistentCollection(
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
Object collectionKey,
|
||||
RowProcessingState rowProcessingState) {
|
||||
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
|
||||
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||
|
||||
final CollectionPersister collectionDescriptor = fetchedMapping.getCollectionDescriptor();
|
||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
||||
|
||||
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||
|
||||
return collectionSemantics.instantiateWrapper(
|
||||
collectionKey,
|
||||
collectionDescriptor,
|
||||
rowProcessingState.getSession()
|
||||
);
|
||||
}
|
||||
final Object key = collectionKey.getKey();
|
||||
|
||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||
key,
|
||||
collectionDescriptor,
|
||||
|
@ -162,19 +74,12 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
|
|||
key
|
||||
);
|
||||
|
||||
private EntityInitializer getEntityInitializer(RowProcessingState rowProcessingState) {
|
||||
Initializer initializer = rowProcessingState.resolveInitializer( getNavigablePath().getParent() );
|
||||
while ( !( initializer instanceof EntityInitializer ) ) {
|
||||
initializer = rowProcessingState.resolveInitializer( initializer.getNavigablePath().getParent() );
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
|
||||
session.getPersistenceContext().addCollectionHolder( collectionInstance );
|
||||
}
|
||||
}
|
||||
return (EntityInitializer) initializer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
}
|
||||
|
@ -186,23 +91,7 @@ public class DelayedCollectionInitializer implements CollectionInitializer {
|
|||
|
||||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
collectionKey = null;
|
||||
instance = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluralAttributeMapping getInitializedPart() {
|
||||
return fetchedMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentCollection getCollectionInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionKey resolveCollectionKey(RowProcessingState rowProcessingState) {
|
||||
resolveKey( rowProcessingState );
|
||||
return collectionKey;
|
||||
super.finishUpRow( rowProcessingState );
|
||||
collectionInstance = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,41 +6,17 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.collection.internal;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentArrayHolder;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EagerCollectionAssembler implements DomainResultAssembler {
|
||||
private final PluralAttributeMapping fetchedMapping;
|
||||
private final CollectionInitializer initializer;
|
||||
public class EagerCollectionAssembler extends AbstractCollectionAssembler {
|
||||
|
||||
public EagerCollectionAssembler(
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
CollectionInitializer initializer) {
|
||||
this.fetchedMapping = fetchedMapping;
|
||||
this.initializer = initializer;
|
||||
super( fetchedMapping, initializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
PersistentCollection collectionInstance = initializer.getCollectionInstance();
|
||||
if ( collectionInstance instanceof PersistentArrayHolder ) {
|
||||
return collectionInstance.getValue();
|
||||
}
|
||||
return collectionInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getAssembledJavaTypeDescriptor() {
|
||||
return fetchedMapping.getJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,10 +49,9 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
|
|||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedAttribute,
|
||||
TableGroup collectionTableGroup,
|
||||
boolean nullable,
|
||||
FetchParent fetchParent,
|
||||
DomainResultCreationState creationState) {
|
||||
super( fetchedPath, fetchedAttribute, nullable, fetchParent );
|
||||
super( fetchedPath, fetchedAttribute, fetchParent );
|
||||
|
||||
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
|
||||
final NavigablePath parentPath = fetchedPath.getParent();
|
||||
|
@ -91,7 +90,7 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
|
|||
fetchedPath,
|
||||
fetchedAttribute,
|
||||
fetchParent,
|
||||
nullable,
|
||||
true,
|
||||
null,
|
||||
// todo (6.0) : we need to propagate these lock modes
|
||||
LockMode.READ,
|
||||
|
|
|
@ -33,13 +33,12 @@ public class ListInitializer extends AbstractImmediateCollectionInitializer {
|
|||
NavigablePath navigablePath,
|
||||
PluralAttributeMapping attributeMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler,
|
||||
DomainResultAssembler listIndexAssembler,
|
||||
DomainResultAssembler elementAssembler) {
|
||||
super( navigablePath, attributeMapping, parentAccess, selected, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
super( navigablePath, attributeMapping, parentAccess, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
this.listIndexAssembler = listIndexAssembler;
|
||||
this.elementAssembler = elementAssembler;
|
||||
|
||||
|
|
|
@ -24,17 +24,14 @@ import org.hibernate.sql.results.graph.Initializer;
|
|||
*/
|
||||
public class ListInitializerProducer implements CollectionInitializerProducer {
|
||||
private final PluralAttributeMapping attributeMapping;
|
||||
private final boolean joined;
|
||||
private final Fetch listIndexFetch;
|
||||
private final Fetch elementFetch;
|
||||
|
||||
public ListInitializerProducer(
|
||||
PluralAttributeMapping attributeMapping,
|
||||
boolean joined,
|
||||
Fetch listIndexFetch,
|
||||
Fetch elementFetch) {
|
||||
this.attributeMapping = attributeMapping;
|
||||
this.joined = joined;
|
||||
this.listIndexFetch = listIndexFetch;
|
||||
this.elementFetch = elementFetch;
|
||||
}
|
||||
|
@ -53,7 +50,6 @@ public class ListInitializerProducer implements CollectionInitializerProducer {
|
|||
navigablePath,
|
||||
attributeMapping,
|
||||
parentAccess,
|
||||
joined,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler,
|
||||
|
|
|
@ -34,13 +34,12 @@ public class MapInitializer extends AbstractImmediateCollectionInitializer {
|
|||
NavigablePath navigablePath,
|
||||
PluralAttributeMapping attributeMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler,
|
||||
DomainResultAssembler mapKeyAssembler,
|
||||
DomainResultAssembler mapValueAssembler) {
|
||||
super( navigablePath, attributeMapping, parentAccess, selected, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
super( navigablePath, attributeMapping, parentAccess, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
this.mapKeyAssembler = mapKeyAssembler;
|
||||
this.mapValueAssembler = mapValueAssembler;
|
||||
}
|
||||
|
|
|
@ -24,17 +24,14 @@ import org.hibernate.sql.results.graph.Initializer;
|
|||
*/
|
||||
public class MapInitializerProducer implements CollectionInitializerProducer {
|
||||
private final PluralAttributeMapping mapDescriptor;
|
||||
private final boolean isJoined;
|
||||
private final Fetch mapKeyFetch;
|
||||
private final Fetch mapValueFetch;
|
||||
|
||||
public MapInitializerProducer(
|
||||
PluralAttributeMapping mapDescriptor,
|
||||
boolean isJoined,
|
||||
Fetch mapKeyFetch,
|
||||
Fetch mapValueFetch) {
|
||||
this.mapDescriptor = mapDescriptor;
|
||||
this.isJoined = isJoined;
|
||||
this.mapKeyFetch = mapKeyFetch;
|
||||
this.mapValueFetch = mapValueFetch;
|
||||
}
|
||||
|
@ -65,7 +62,6 @@ public class MapInitializerProducer implements CollectionInitializerProducer {
|
|||
navigablePath,
|
||||
mapDescriptor,
|
||||
parentAccess,
|
||||
isJoined,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler,
|
||||
|
|
|
@ -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.collection.internal;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class SelectEagerCollectionAssembler extends AbstractCollectionAssembler {
|
||||
|
||||
public SelectEagerCollectionAssembler(
|
||||
NavigablePath fetchPath,
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
FetchParentAccess parentAccess,
|
||||
Consumer<Initializer> collector,
|
||||
AssemblerCreationState creationState) {
|
||||
super( fetchedMapping, new SelectEagerCollectionInitializer( fetchPath, fetchedMapping, parentAccess ) );
|
||||
collector.accept( initializer );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.collection.internal;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class SelectEagerCollectionFetch extends CollectionFetch {
|
||||
public SelectEagerCollectionFetch(
|
||||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedAttribute,
|
||||
FetchParent fetchParent) {
|
||||
super( fetchedPath, fetchedAttribute, fetchParent );
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchTiming getTiming() {
|
||||
return FetchTiming.DELAYED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTableGroup() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess, Consumer<Initializer> collector, AssemblerCreationState creationState) {
|
||||
return new SelectEagerCollectionAssembler(
|
||||
getNavigablePath(),
|
||||
getFetchedMapping(),
|
||||
parentAccess,
|
||||
collector,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
||||
return getFetchedMapping().getJavaTypeDescriptor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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.collection.internal;
|
||||
|
||||
import org.hibernate.collection.spi.CollectionSemantics;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.log.LoggingHelper;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.collection.LoadingCollectionEntry;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class SelectEagerCollectionInitializer extends AbstractCollectionInitializer {
|
||||
|
||||
public SelectEagerCollectionInitializer(
|
||||
NavigablePath fetchedPath,
|
||||
PluralAttributeMapping fetchedMapping,
|
||||
FetchParentAccess parentAccess) {
|
||||
super( fetchedPath, fetchedMapping, parentAccess );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
if ( collectionKey != null ) {
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
|
||||
final LoadingCollectionEntry loadingEntry = persistenceContext.getLoadContexts()
|
||||
.findLoadingCollectionEntry( collectionKey );
|
||||
|
||||
if ( loadingEntry != null ) {
|
||||
collectionInstance = loadingEntry.getCollectionInstance();
|
||||
return;
|
||||
}
|
||||
|
||||
final PersistentCollection existing = persistenceContext.getCollection( collectionKey );
|
||||
|
||||
if ( existing != null ) {
|
||||
collectionInstance = existing;
|
||||
return;
|
||||
}
|
||||
|
||||
final CollectionPersister collectionDescriptor = collectionAttributeMapping.getCollectionDescriptor();
|
||||
|
||||
final CollectionSemantics collectionSemantics = collectionDescriptor.getCollectionSemantics();
|
||||
|
||||
final Object key = collectionKey.getKey();
|
||||
|
||||
collectionInstance = collectionSemantics.instantiateWrapper(
|
||||
key,
|
||||
collectionDescriptor,
|
||||
session
|
||||
);
|
||||
|
||||
parentAccess.registerResolutionListener(
|
||||
owner -> collectionInstance.setOwner( owner )
|
||||
);
|
||||
|
||||
persistenceContext.addUninitializedCollection(
|
||||
collectionDescriptor,
|
||||
collectionInstance,
|
||||
key
|
||||
);
|
||||
|
||||
persistenceContext.addNonLazyCollection( collectionInstance );
|
||||
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY ) {
|
||||
session.getPersistenceContext().addCollectionHolder( collectionInstance );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SelectEagerCollectionInitializer(" + LoggingHelper.toLoggableString( getNavigablePath() ) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
super.finishUpRow( rowProcessingState );
|
||||
collectionInstance = null;
|
||||
}
|
||||
}
|
|
@ -28,12 +28,11 @@ public class SetInitializer extends AbstractImmediateCollectionInitializer {
|
|||
NavigablePath navigablePath,
|
||||
PluralAttributeMapping setDescriptor,
|
||||
FetchParentAccess parentAccess,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
DomainResultAssembler keyContainerAssembler,
|
||||
DomainResultAssembler keyCollectionAssembler,
|
||||
DomainResultAssembler elementAssembler) {
|
||||
super( navigablePath, setDescriptor, parentAccess, selected, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
super( navigablePath, setDescriptor, parentAccess, lockMode, keyContainerAssembler, keyCollectionAssembler );
|
||||
this.elementAssembler = elementAssembler;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,13 @@ import org.hibernate.sql.results.graph.Initializer;
|
|||
*/
|
||||
public class SetInitializerProducer implements CollectionInitializerProducer {
|
||||
private final PluralAttributeMapping setDescriptor;
|
||||
private final boolean isSelected;
|
||||
private final Fetch elementFetch;
|
||||
|
||||
public SetInitializerProducer(
|
||||
PluralAttributeMapping setDescriptor,
|
||||
boolean isSelected,
|
||||
Fetch elementFetch) {
|
||||
this.setDescriptor = setDescriptor;
|
||||
this.elementFetch = elementFetch;
|
||||
this.isSelected = isSelected;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,7 +53,6 @@ public class SetInitializerProducer implements CollectionInitializerProducer {
|
|||
navigablePath,
|
||||
setDescriptor,
|
||||
parentAccess,
|
||||
isSelected,
|
||||
lockMode,
|
||||
keyContainerAssembler,
|
||||
keyCollectionAssembler,
|
||||
|
|
|
@ -110,11 +110,6 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
|||
return getFetchContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -61,11 +61,6 @@ public abstract class AbstractNonLazyEntityFetch extends AbstractFetchParent imp
|
|||
return (Fetchable) getEntityValuedModelPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -54,11 +54,6 @@ public class EntityFetchDelayedImpl extends AbstractNonJoinedEntityFetch {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -52,11 +52,6 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -88,11 +88,6 @@ public class BiDirectionalFetchImpl implements BiDirectionalFetch, Association {
|
|||
return fetchable.getJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler createAssembler(
|
||||
FetchParentAccess parentAccess,
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.sql.SQLException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValues;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
|
@ -47,7 +48,8 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
RowProcessingStateStandardImpl rowProcessingState,
|
||||
RowReader<R> rowReader) {
|
||||
try {
|
||||
session.getPersistenceContext().getLoadContexts().register( jdbcValuesSourceProcessingState );
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
persistenceContext.getLoadContexts().register( jdbcValuesSourceProcessingState );
|
||||
|
||||
boolean uniqueRows = false;
|
||||
final Class<R> resultJavaType = rowReader.getResultJavaType();
|
||||
|
@ -76,6 +78,7 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
|
||||
rowProcessingState.finishRowProcessing();
|
||||
}
|
||||
persistenceContext.initializeNonLazyCollections();
|
||||
return results;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
|
|
Loading…
Reference in New Issue