org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* 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 .
*/
package org.hibernate.loader.plan.exec.process.internal;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.internal.CoreLogging;
import org.hibernate.loader.plan.exec.process.spi.CollectionReferenceInitializer;
import org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases;
import org.hibernate.loader.plan.spi.CollectionReference;
import org.hibernate.loader.plan.spi.Fetch;
import org.hibernate.pretty.MessageHelper;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
public class CollectionReferenceInitializerImpl implements CollectionReferenceInitializer {
private static final Logger log = CoreLogging.logger( CollectionReferenceInitializerImpl.class );
private final CollectionReference collectionReference;
private final CollectionReferenceAliases aliases;
public CollectionReferenceInitializerImpl(CollectionReference collectionReference, CollectionReferenceAliases aliases) {
this.collectionReference = collectionReference;
this.aliases = aliases;
}
@Override
public CollectionReference getCollectionReference() {
return collectionReference;
}
@Override
public void finishUpRow(ResultSet resultSet, ResultSetProcessingContextImpl context) {
try {
// read the collection key for this reference for the current row.
final PersistenceContext persistenceContext = context.getSession().getPersistenceContext();
final Serializable collectionRowKey = (Serializable) collectionReference.getCollectionPersister().readKey(
resultSet,
aliases.getCollectionColumnAliases().getSuffixedKeyAliases(),
context.getSession()
);
if ( collectionRowKey != null ) {
// we found a collection element in the result set
if ( log.isDebugEnabled() ) {
log.debugf(
"Found row of collection: %s",
MessageHelper.collectionInfoString(
collectionReference.getCollectionPersister(),
collectionRowKey,
context.getSession().getFactory()
)
);
}
Object collectionOwner = findCollectionOwner( collectionRowKey, resultSet, context );
PersistentCollection rowCollection = persistenceContext.getLoadContexts()
.getCollectionLoadContext( resultSet )
.getLoadingCollection( collectionReference.getCollectionPersister(), collectionRowKey );
if ( rowCollection != null ) {
rowCollection.readFrom(
resultSet,
collectionReference.getCollectionPersister(),
aliases.getCollectionColumnAliases(),
collectionOwner
);
}
}
else {
final Serializable optionalKey = findCollectionOwnerKey( context );
if ( optionalKey != null ) {
// we did not find a collection element in the result set, so we
// ensure that a collection is created with the owner's identifier,
// since what we have is an empty collection
if ( log.isDebugEnabled() ) {
log.debugf(
"Result set contains (possibly empty) collection: %s",
MessageHelper.collectionInfoString(
collectionReference.getCollectionPersister(),
optionalKey,
context.getSession().getFactory()
)
);
}
// handle empty collection
persistenceContext.getLoadContexts()
.getCollectionLoadContext( resultSet )
.getLoadingCollection( collectionReference.getCollectionPersister(), optionalKey );
}
}
// else no collection element, but also no owner
}
catch ( SQLException sqle ) {
// TODO: would be nice to have the SQL string that failed...
throw context.getSession().getFactory().getSQLExceptionHelper().convert(
sqle,
"could not read next row of results"
);
}
}
protected Object findCollectionOwner(
Serializable collectionRowKey,
ResultSet resultSet,
ResultSetProcessingContextImpl context) {
final Object collectionOwner = context.getSession().getPersistenceContext().getCollectionOwner(
collectionRowKey,
collectionReference.getCollectionPersister()
);
// todo : try org.hibernate.loader.plan.exec.process.spi.ResultSetProcessingContext.getOwnerProcessingState() ??
// -- specifically to return its ResultSetProcessingContext.EntityReferenceProcessingState#getEntityInstance()
if ( collectionOwner == null ) {
//TODO: This is assertion is disabled because there is a bug that means the
// original owner of a transient, uninitialized collection is not known
// if the collection is re-referenced by a different object associated
// with the current Session
//throw new AssertionFailure("bug loading unowned collection");
}
return collectionOwner;
}
protected Serializable findCollectionOwnerKey(ResultSetProcessingContextImpl context) {
Object owner = context.getOwnerProcessingState( (Fetch) collectionReference ).getEntityInstance();
return collectionReference.getCollectionPersister().getCollectionType().getKeyOfOwner(
owner,
context.getSession()
);
}
@Override
public void endLoading(ResultSetProcessingContextImpl context) {
context.getSession().getPersistenceContext()
.getLoadContexts()
.getCollectionLoadContext( context.getResultSet() )
.endLoadingCollections( collectionReference.getCollectionPersister() );
}
}