rework collection loading state management - remove the "temp" load collections in various PersistentCollection impls

This commit is contained in:
Steve Ebersole 2020-01-31 14:18:49 -06:00
parent cb3560de96
commit 8fd1f9a536
15 changed files with 234 additions and 248 deletions

View File

@ -12,14 +12,14 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
@ -41,7 +41,6 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
//just to help out during the load (ugly, i know)
private transient Class elementClass;
private transient java.util.List tempList;
/**
* Constructs a PersistentCollection instance for holding an array.
@ -130,6 +129,15 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
return result;
}
@Override
public void injectLoadedState(PluralAttributeMapping attributeMapping, List loadingState) {
assert isInitializing();
array = Array.newInstance( elementClass, loadingState.size() );
for ( int i = 0; i < loadingState.size(); i++ ) {
Array.set( array, i, loadingState.get( i ) );
}
}
@SuppressWarnings("UnusedDeclaration")
public Object getArray() {
return array;
@ -177,32 +185,6 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
}
@Override
public Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException {
assert elementAssembler != null;
assert indexAssembler != null;
assert identifierAssembler == null;
final Object element = elementAssembler.assemble( rowProcessingState );
final int index = (int) indexAssembler.assemble( rowProcessingState );
for ( int i = tempList.size(); i<=index; i++) {
//noinspection unchecked
tempList.add( i, null );
}
//noinspection unchecked
tempList.set( index, element );
return element;
}
@Override
@SuppressWarnings("unchecked")
public Iterator entries(CollectionPersister persister) {
return elements();
}
@ -210,17 +192,11 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
@Override
public void beginRead() {
super.beginRead();
tempList = new ArrayList();
}
@Override
public boolean endRead() {
setInitialized();
array = Array.newInstance( elementClass, tempList.size() );
for ( int i=0; i<tempList.size(); i++ ) {
Array.set( array, i, tempList.get( i ) );
}
tempList = null;
return true;
}
@ -320,14 +296,4 @@ public class PersistentArrayHolder extends AbstractPersistentCollection {
public boolean entryExists(Object entry, int i) {
return entry != null;
}
public void load(int index, Object element) {
assert isInitializing();
for ( int i = tempList.size(); i <= index; ++i ) {
tempList.add( i, null );
}
tempList.set( index, element );
}
}

View File

@ -19,6 +19,7 @@ import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -36,7 +37,9 @@ public class PersistentBag extends AbstractPersistentCollection implements List
protected List bag;
// The Collection provided to a PersistentBag constructor,
/**
* The Collection provided to a PersistentBag constructor
*/
private Collection providedCollection;
/**
@ -121,22 +124,15 @@ public class PersistentBag extends AbstractPersistentCollection implements List
return bag.iterator();
}
@Override
public Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException {
assert indexAssembler == null;
assert identifierAssembler == null;
public void injectLoadedState(PluralAttributeMapping collectionAttributeMapping, List loadingState) {
assert isInitializing();
assert bag != null;
assert bag.isEmpty();
final Object element = elementAssembler.assemble( rowProcessingState );
if ( element != null ) {
//noinspection unchecked
bag.add( element );
for ( int i = 0; i < loadingState.size(); i++ ) {
//noinspection unchecked,UseBulkOperation
bag.add( loadingState.get( i ) );
}
return element;
}
@Override
@ -645,11 +641,6 @@ public class PersistentBag extends AbstractPersistentCollection implements List
return super.hashCode();
}
public void load(Object element) {
assert isInitializing();
bag.add( element );
}
final class Clear implements DelayedOperation {
@Override
public void operate() {

View File

@ -18,6 +18,7 @@ import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -39,7 +40,9 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
protected List<Object> values;
protected Map<Integer, Object> identifiers;
// The Collection provided to a PersistentIdentifierBag constructor,
/**
* The Collection provided to a PersistentIdentifierBag constructor
*/
private Collection providedValues;
/**
@ -530,4 +533,24 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
values.add( element );
}
}
public void injectLoadedState(PluralAttributeMapping attributeMapping, List loadingState) {
assert isInitializing();
assert identifiers != null;
assert identifiers.isEmpty();
assert values != null;
assert values.isEmpty();
for ( int i = 0; i < loadingState.size(); i++ ) {
final Object[] row = (Object[]) loadingState.get( i );
final Object identifier = row[0];
final Object element = row[1];
Object old = identifiers.put( values.size(), identifier );
if ( old == null ) {
//maintain correct duplication if loaded in a cartesian product
values.add( element );
}
}
}
}

View File

@ -16,9 +16,8 @@ import java.util.ListIterator;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.type.Type;
/**
@ -394,33 +393,6 @@ public class PersistentList extends AbstractPersistentCollection implements List
}
@Override
public Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException {
assert elementAssembler != null;
assert indexAssembler != null;
assert identifierAssembler == null;
final Object element = elementAssembler.assemble( rowProcessingState );
final int index = (int) indexAssembler.assemble( rowProcessingState );
//pad with nulls from the current last element up to the new index
for ( int i = list.size(); i<=index; i++) {
//noinspection unchecked
list.add( i, null );
}
//noinspection unchecked
list.set( index, element );
return element;
}
@Override
@SuppressWarnings("unchecked")
public Iterator entries(CollectionPersister persister) {
return list.iterator();
}
@ -521,6 +493,14 @@ public class PersistentList extends AbstractPersistentCollection implements List
return entry!=null;
}
public void injectLoadedState(PluralAttributeMapping collectionAttributeMapping, List loadingStateList) {
assert isInitializing();
assert list != null;
//noinspection unchecked
list.addAll( loadingStateList );
}
final class Clear implements DelayedOperation {
@Override
public void operate() {

View File

@ -18,9 +18,8 @@ import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.type.Type;
@ -274,50 +273,27 @@ public class PersistentMap extends AbstractPersistentCollection implements Map {
return map.toString();
}
private transient List<Object[]> loadingEntries;
@Override
public Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException {
assert elementAssembler != null;
assert indexAssembler != null;
assert identifierAssembler == null;
final Object element = elementAssembler.assemble( rowProcessingState );
if ( element != null ) {
final Object index = indexAssembler.assemble( rowProcessingState );
if ( loadingEntries == null ) {
loadingEntries = new ArrayList<>();
}
loadingEntries.add( new Object[] { index, element } );
}
return element;
}
@Override
@SuppressWarnings("unchecked")
public boolean endRead() {
if ( loadingEntries != null ) {
for ( Object[] entry : loadingEntries ) {
map.put( entry[0], entry[1] );
}
loadingEntries = null;
}
return super.endRead();
}
@Override
@SuppressWarnings("unchecked")
public Iterator entries(CollectionPersister persister) {
return map.entrySet().iterator();
}
public void injectLoadedState(PluralAttributeMapping collectionAttributeMapping, List loadingState) {
assert isInitializing();
assert map != null;
for ( int i = 0; i < loadingState.size(); i++ ) {
final Object[] keyVal = (Object[]) loadingState.get( i );
//noinspection unchecked
map.put( keyVal[0], keyVal[1] );
}
}
/**
* a wrapper for Map.Entry sets
*/

View File

@ -17,6 +17,7 @@ import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -32,7 +33,6 @@ import org.hibernate.type.Type;
*/
public class PersistentSet extends AbstractPersistentCollection implements java.util.Set {
protected Set set;
protected transient List tempList;
/**
* Empty constructor.
@ -141,12 +141,6 @@ public class PersistentSet extends AbstractPersistentCollection implements java.
this.set = (Set) persister.getCollectionType().instantiate( anticipatedSize );
}
@SuppressWarnings("unchecked")
public void load(Object element) {
assert isInitializing();
tempList.add( element );
}
@Override
@SuppressWarnings("unchecked")
public void initializeFromCache(CollectionPersister persister, Object disassembled, Object owner)
@ -312,7 +306,6 @@ public class PersistentSet extends AbstractPersistentCollection implements java.
}
@Override
@SuppressWarnings("unchecked")
public void clear() {
if ( isClearQueueEnabled() ) {
queueOperation( new Clear() );
@ -327,51 +320,25 @@ public class PersistentSet extends AbstractPersistentCollection implements java.
}
@Override
@SuppressWarnings("unchecked")
public String toString() {
read();
return set.toString();
}
@Override
public Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException {
assert elementAssembler != null;
assert indexAssembler == null;
assert identifierAssembler == null;
public void injectLoadedState(
PluralAttributeMapping attributeMapping,
List loadingStateList) {
final CollectionPersister collectionDescriptor = attributeMapping.getCollectionDescriptor();
this.set = (Set) attributeMapping.getCollectionDescriptor().getCollectionSemantics().instantiateRaw(
loadingStateList.size(),
collectionDescriptor
);
final Object element = elementAssembler.assemble( rowProcessingState );
if ( element != null ) {
//noinspection unchecked
tempList.add( element );
}
return element;
this.set.addAll( loadingStateList );
}
@Override
@SuppressWarnings("unchecked")
public void beginRead() {
super.beginRead();
tempList = new ArrayList();
}
@Override
@SuppressWarnings("unchecked")
public boolean endRead() {
set.addAll( tempList );
tempList = null;
// ensure that operationQueue is considered
return super.endRead();
}
@Override
@SuppressWarnings("unchecked")
public Iterator entries(CollectionPersister persister) {
return set.iterator();
}

View File

@ -9,9 +9,11 @@ package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -91,6 +93,8 @@ public interface PersistentCollection {
/**
* Called just before reading any rows from the JDBC result set
*
* todo (6.0) remove these. should no longer be a need with change in how collections are initialized
*/
void beginRead();
@ -98,6 +102,8 @@ public interface PersistentCollection {
* Called after reading all rows from the JDBC result set
*
* @return Whether to end the read.
*
* todo (6.0) remove these. should no longer be a need with change in how collections are initialized
*/
boolean endRead();
@ -105,6 +111,8 @@ public interface PersistentCollection {
* Called after initializing from cache
*
* @return ??
*
* todo (6.0) remove these. should no longer be a need with change in how collections are initialized
*/
boolean afterInitialize();
@ -158,13 +166,18 @@ public interface PersistentCollection {
* Read a row from the JDBC values
*
* @throws HibernateException Generally indicates a problem resolving data read from the ResultSet
*
*
todo (6.0) remove these. should no longer be a need with change in how collections are initialized
*/
Object readFrom(
default Object readFrom(
RowProcessingState rowProcessingState,
DomainResultAssembler elementAssembler,
DomainResultAssembler indexAssembler,
DomainResultAssembler identifierAssembler,
Object owner) throws HibernateException;
Object owner) throws HibernateException {
return null;
}
/**
* Get the identifier of the given collection entry. This refers to the collection identifier, not the
@ -458,4 +471,8 @@ public interface PersistentCollection {
*/
Collection getOrphans(Serializable snapshot, String entityName);
/**
* Inject the state loaded for a collection instance.
*/
void injectLoadedState(PluralAttributeMapping attributeMapping, List loadingState);
}

View File

@ -7,6 +7,8 @@
package org.hibernate.sql.results.graph.collection;
import java.io.Serializable;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.persister.collection.CollectionPersister;
@ -18,13 +20,33 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
* @author Steve Ebersole
*/
public interface LoadingCollectionEntry {
/**
* The descriptor for the collection being loaded
*/
CollectionPersister getCollectionDescriptor();
/**
* The initializer responsible for the loading
*/
CollectionInitializer getInitializer();
/**
* The collection key.
*/
Serializable getKey();
/**
* The collection instance being loaded
*/
PersistentCollection getCollectionInstance();
/**
* Callback for row loading. Allows delayed List creation
*/
void load(Consumer<List> loadingEntryConsumer);
/**
* Complete the load
*/
void finishLoading(ExecutionContext executionContext);
}

View File

@ -6,24 +6,24 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry;
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.internal.util.StringHelper;
import org.hibernate.sql.results.graph.collection.CollectionLoadingLogger;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.results.internal.LoadingCollectionEntryImpl;
import org.hibernate.sql.results.graph.DomainResultAssembler;
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.RowProcessingState;
/**
@ -41,8 +41,8 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
// per-row state
private PersistentCollection collectionInstance;
private LoadingCollectionEntryImpl responsibility;
private boolean responsible;
private boolean collectionEmpty = true;
public AbstractImmediateCollectionInitializer(
NavigablePath collectionPath,
@ -110,7 +110,7 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
if ( existingLoadingEntry.getInitializer() == this ) {
// we are responsible for loading the collection values
responsible = true;
responsibility = (LoadingCollectionEntryImpl) existingLoadingEntry;
}
else {
// the entity is already being loaded elsewhere
@ -215,7 +215,7 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
takeResponsibility( rowProcessingState, collectionKey );
}
if ( responsible ) {
if ( responsibility != null ) {
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
CollectionLoadingLogger.INSTANCE.debugf(
"(%s) Responsible for loading collection [%s] : %s",
@ -238,32 +238,31 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
}
protected void takeResponsibility(RowProcessingState rowProcessingState, CollectionKey collectionKey) {
rowProcessingState.getJdbcValuesSourceProcessingState().registerLoadingCollection(
collectionKey,
new LoadingCollectionEntryImpl(
responsibility = new LoadingCollectionEntryImpl(
getCollectionAttributeMapping().getCollectionDescriptor(),
this,
collectionKey.getKey(),
collectionInstance
)
);
responsible = true;
rowProcessingState.getJdbcValuesSourceProcessingState().registerLoadingCollection(
collectionKey,
responsibility
);
}
@Override
public void initializeInstance(RowProcessingState rowProcessingState) {
if ( !responsible ) {
if ( responsibility == null ) {
return;
}
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
// the LHS key value of the association
final CollectionKey collectionKey = resolveCollectionKey( rowProcessingState );
// the RHS key value of the association
final Object keyCollectionValue = getKeyCollectionValue();
if ( keyCollectionValue != null ) {
// the RHS key value of the association - determines if the row contains an element of the initializing collection
final Object collectionValueKey = getKeyCollectionValue();
if ( collectionValueKey != null ) {
// the row contains an element in the collection...
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
CollectionLoadingLogger.INSTANCE.debugf(
@ -274,45 +273,20 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
);
}
readCollectionRow( rowProcessingState );
collectionEmpty = false;
responsibility.load(
loadingState -> readCollectionRow( collectionKey, loadingState, rowProcessingState )
);
}
}
protected abstract void readCollectionRow(RowProcessingState rowProcessingState);
protected abstract void readCollectionRow(CollectionKey collectionKey, List loadingState, RowProcessingState rowProcessingState);
@Override
public void finishUpRow(RowProcessingState rowProcessingState) {
super.finishUpRow( rowProcessingState );
collectionInstance = null;
responsible = false;
collectionEmpty = true;
responsibility = null;
}
@Override
public void endLoading(ExecutionContext context) {
if ( getParentAccess() == null && collectionEmpty ) {
// collection is empty; handle special logic here.
final CollectionKey collectionKey = context.getCollectionKey();
if ( collectionKey != null ) {
// We expected to load a collection with this collection key but we found the collection
// contained no results, therefore we need to do the collection init phase here because
// the LoadingCollectionEntry won't finalize this for us without at least one row.
final PersistenceContext persistenceContext = context.getSession().getPersistenceContext();
final PersistentCollection collection = persistenceContext.getCollection( collectionKey );
if ( ! collection.isInitializing() ) {
collection.beforeInitialize( getCollectionAttributeMapping().getCollectionDescriptor(), 0 );
collection.beginRead();
collection.endRead();
final CollectionEntry entry = persistenceContext.getCollectionEntry( collection );
if ( entry != null ) {
entry.postInitialize( collection );
}
}
}
}
}
}

View File

@ -6,8 +6,11 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentArrayHolder;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath;
@ -55,12 +58,23 @@ public class ArrayInitializer extends AbstractImmediateCollectionInitializer {
}
@Override
protected void readCollectionRow(RowProcessingState rowProcessingState) {
protected void readCollectionRow(
CollectionKey collectionKey,
List loadingState,
RowProcessingState rowProcessingState) {
int index = (int) listIndexAssembler.assemble( rowProcessingState );
if ( indexBase != 0 ) {
index -= indexBase;
}
getCollectionInstance().load( index, elementAssembler.assemble( rowProcessingState ) );
for ( int i = loadingState.size(); i <= index; ++i ) {
//noinspection unchecked
loadingState.add( i, null );
}
//noinspection unchecked
loadingState.set( index, elementAssembler.assemble( rowProcessingState ) );
}
@Override

View File

@ -6,9 +6,12 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentBag;
import org.hibernate.collection.internal.PersistentIdentifierBag;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath;
@ -42,16 +45,21 @@ public class BagInitializer extends AbstractImmediateCollectionInitializer {
}
@Override
@SuppressWarnings("unchecked")
protected void readCollectionRow(RowProcessingState rowProcessingState) {
protected void readCollectionRow(
CollectionKey collectionKey,
List loadingState,
RowProcessingState rowProcessingState) {
if ( collectionIdAssembler != null ) {
( (PersistentIdentifierBag) getCollectionInstance() ).load(
collectionIdAssembler.assemble( rowProcessingState ),
elementAssembler.assemble( rowProcessingState )
);
final Object[] row = new Object[2];
row[0] = collectionIdAssembler.assemble( rowProcessingState );
row[1] = elementAssembler.assemble( rowProcessingState );
//noinspection unchecked
loadingState.add( row );
}
else {
( (PersistentBag) getCollectionInstance() ).load( elementAssembler.assemble( rowProcessingState ) );
//noinspection unchecked
loadingState.add( elementAssembler.assemble( rowProcessingState ) );
}
}

View File

@ -6,8 +6,11 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentList;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath;
@ -49,13 +52,23 @@ public class ListInitializer extends AbstractImmediateCollectionInitializer {
}
@Override
protected void readCollectionRow(RowProcessingState rowProcessingState) {
protected void readCollectionRow(
CollectionKey collectionKey,
List loadingState,
RowProcessingState rowProcessingState) {
int index = (int) listIndexAssembler.assemble( rowProcessingState );
getCollectionAttributeMapping().getIndexMetadata().getIndexDescriptor();
if ( listIndexBase != 0 ) {
index -= listIndexBase;
}
getCollectionInstance().load( index, elementAssembler.assemble( rowProcessingState ) );
for ( int i = loadingState.size(); i <= index; ++i ) {
//noinspection unchecked
loadingState.add( i, null );
}
//noinspection unchecked
loadingState.set( index, elementAssembler.assemble( rowProcessingState ) );
}
@Override

View File

@ -6,8 +6,11 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath;
@ -48,11 +51,16 @@ public class MapInitializer extends AbstractImmediateCollectionInitializer {
}
@Override
@SuppressWarnings("unchecked")
protected void readCollectionRow(RowProcessingState rowProcessingState) {
getCollectionInstance().load(
protected void readCollectionRow(
CollectionKey collectionKey,
List loadingState,
RowProcessingState rowProcessingState) {
//noinspection unchecked
loadingState.add(
new Object[] {
mapKeyAssembler.assemble( rowProcessingState ),
mapValueAssembler.assemble( rowProcessingState )
}
);
}

View File

@ -6,8 +6,11 @@
*/
package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentSet;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath;
@ -40,8 +43,12 @@ public class SetInitializer extends AbstractImmediateCollectionInitializer {
}
@Override
protected void readCollectionRow(RowProcessingState rowProcessingState) {
getCollectionInstance().load( elementAssembler.assemble( rowProcessingState ) );
protected void readCollectionRow(
CollectionKey collectionKey,
List loadingState,
RowProcessingState rowProcessingState) {
//noinspection unchecked
loadingState.add( elementAssembler.assemble( rowProcessingState ) );
}
@Override

View File

@ -7,7 +7,11 @@
package org.hibernate.sql.results.internal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.collection.internal.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.BatchFetchQueue;
import org.hibernate.engine.spi.CollectionEntry;
@ -29,6 +33,8 @@ public class LoadingCollectionEntryImpl implements LoadingCollectionEntry {
private final Object key;
private final PersistentCollection collectionInstance;
private List loadingState;
public LoadingCollectionEntryImpl(
CollectionPersister collectionDescriptor,
CollectionInitializer initializer,
@ -64,13 +70,22 @@ public class LoadingCollectionEntryImpl implements LoadingCollectionEntry {
}
@Override
public String toString() {
return getClass().getSimpleName() + "(" + getCollectionDescriptor().getNavigableRole().getFullPath() + "#" + getKey() + ")";
public void load(Consumer<List> loadingEntryConsumer) {
if ( loadingState == null ) {
loadingState = new ArrayList();
}
loadingEntryConsumer.accept( loadingState );
}
@Override public void finishLoading(ExecutionContext executionContext) {
collectionInstance.injectLoadedState(
getCollectionDescriptor().getAttributeMapping(),
loadingState
);
collectionInstance.endRead();
final SharedSessionContractImplementor session = executionContext.getSession();
final PersistenceContext persistenceContext = session.getPersistenceContext();
final CollectionPersister collectionDescriptor = getCollectionDescriptor();
@ -97,4 +112,9 @@ public class LoadingCollectionEntryImpl implements LoadingCollectionEntry {
// todo (6.0) : there is other logic still needing to be implemented here. caching, etc
// see org.hibernate.engine.loading.internal.CollectionLoadContext#endLoadingCollection in 5.x
}
@Override
public String toString() {
return getClass().getSimpleName() + "(" + getCollectionDescriptor().getNavigableRole().getFullPath() + "#" + getKey() + ")";
}
}