HHH-7841 - Redesign Loader

This commit is contained in:
Gail Badner 2013-05-21 00:51:15 -07:00
parent a03d44f290
commit b846fa35b5
29 changed files with 326 additions and 76 deletions

View File

@ -58,7 +58,7 @@ public class EntityJoinableAssociationImpl extends AbstractJoinableAssociationIm
hasRestriction, hasRestriction,
enabledFilters enabledFilters
); );
this.joinableType = entityFetch.getAssociationType(); this.joinableType = entityFetch.getEntityType();
this.joinable = (Joinable) entityFetch.getEntityPersister(); this.joinable = (Joinable) entityFetch.getEntityPersister();
} }

View File

@ -64,7 +64,6 @@ public class LoadPlanBuildingHelper {
LockMode.NONE, // todo : for now LockMode.NONE, // todo : for now
fetchOwner, fetchOwner,
attributeDefinition.getName(), attributeDefinition.getName(),
(EntityType) attributeDefinition.getType(),
fetchStrategy fetchStrategy
); );
} }

View File

@ -36,11 +36,17 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* This is a class for fetch owners, providing functionality related to the owned
* fetches.
*
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner * @author Gail Badner
*/ */
public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner { public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner {
// TODO: I removed lockMode from this method because I *think* it only relates to EntityFetch and EntityReturn.
// lockMode should be moved back here if it applies to all fetch owners.
private List<Fetch> fetches; private List<Fetch> fetches;
public AbstractFetchOwner(SessionFactoryImplementor factory) { public AbstractFetchOwner(SessionFactoryImplementor factory) {
@ -55,17 +61,18 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
* A "copy" constructor. Used while making clones/copies of this. * A "copy" constructor. Used while making clones/copies of this.
* *
* @param original - the original object to copy. * @param original - the original object to copy.
* @param copyContext - the copy context.
*/ */
protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) { protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) {
super( original ); super( original );
validate(); validate();
// TODO: I don't think this is correct; shouldn't the fetches from original be copied into this???
copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) { if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList(); this.fetches = Collections.emptyList();
} }
else { else {
// TODO: don't think this is correct...
List<Fetch> fetchesCopy = new ArrayList<Fetch>(); List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) { for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
@ -75,6 +82,7 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
} }
@Override
public void addFetch(Fetch fetch) { public void addFetch(Fetch fetch) {
if ( fetch.getOwner() != this ) { if ( fetch.getOwner() != this ) {
throw new IllegalArgumentException( "Fetch and owner did not match" ); throw new IllegalArgumentException( "Fetch and owner did not match" );
@ -92,6 +100,10 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
} }
/**
* Abstract method returning the delegate for obtaining details about an owned fetch.
* @return the delegate
*/
protected abstract FetchOwnerDelegate getFetchOwnerDelegate(); protected abstract FetchOwnerDelegate getFetchOwnerDelegate();
@Override @Override

View File

@ -30,7 +30,10 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
/** /**
* Represents a singular attribute that is both a {@link FetchOwner} and a {@link Fetch}.
*
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner
*/ */
public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner implements Fetch { public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner implements Fetch {
private final FetchOwner owner; private final FetchOwner owner;
@ -39,6 +42,14 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
private final PropertyPath propertyPath; private final PropertyPath propertyPath;
/**
* Constructs an {@link AbstractSingularAttributeFetch} object.
*
* @param factory - the session factory.
* @param owner - the fetch owner for this fetch.
* @param ownerProperty - the owner's property referring to this fetch.
* @param fetchStrategy - the fetch strategy for this fetch.
*/
public AbstractSingularAttributeFetch( public AbstractSingularAttributeFetch(
SessionFactoryImplementor factory, SessionFactoryImplementor factory,
FetchOwner owner, FetchOwner owner,

View File

@ -12,7 +12,10 @@ import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
/** /**
* Represents the {@link FetchOwner} for a composite collection element.
*
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner
*/ */
public class CompositeElementGraph extends AbstractFetchOwner implements FetchableCollectionElement { public class CompositeElementGraph extends AbstractFetchOwner implements FetchableCollectionElement {
private final CollectionReference collectionReference; private final CollectionReference collectionReference;
@ -20,6 +23,13 @@ public class CompositeElementGraph extends AbstractFetchOwner implements Fetchab
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
private final FetchOwnerDelegate fetchOwnerDelegate; private final FetchOwnerDelegate fetchOwnerDelegate;
/**
* Constructs a {@link CompositeElementGraph}.
*
* @param sessionFactory - the session factory.
* @param collectionReference - the collection reference.
* @param collectionPath - the {@link PropertyPath} for the collection.
*/
public CompositeElementGraph( public CompositeElementGraph(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference, CollectionReference collectionReference,

View File

@ -29,22 +29,29 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
/** /**
* Represents a {@link Fetch} for a composite attribute as well as a
* {@link FetchOwner} for any sub-attributes fetches.
*
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner
*/ */
public class CompositeFetch extends AbstractSingularAttributeFetch { public class CompositeFetch extends AbstractSingularAttributeFetch {
public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN ); public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
private final FetchOwnerDelegate delegate; private final FetchOwnerDelegate delegate;
/**
* Constructs a {@link CompositeFetch} object.
*
* @param sessionFactory - the session factory.
* @param owner - the fetch owner for this fetch.
* @param ownerProperty - the owner's property referring to this fetch.
*/
public CompositeFetch( public CompositeFetch(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
FetchOwner owner, FetchOwner owner,
@ -72,33 +79,6 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
return getOwner().retrieveFetchSourcePersister(); return getOwner().retrieveFetchSourcePersister();
} }
@Override
public CollectionFetch buildCollectionFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardEntityFetch(
this,
attributeDefinition,
fetchStrategy,
loadPlanBuildingContext
);
}
@Override
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition, LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
}
@Override @Override
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
//To change body of implemented methods use File | Settings | File Templates. //To change body of implemented methods use File | Settings | File Templates.

View File

@ -32,6 +32,9 @@ import org.hibernate.type.CompositeType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* This interface provides a delegate for a composite fetch owner to
* obtain details about an owned sub-attribute fetch.
*
* @author Gail Badner * @author Gail Badner
*/ */
public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate { public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate {
@ -39,6 +42,12 @@ public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate {
private final CompositeType compositeType; private final CompositeType compositeType;
private final String[] columnNames; private final String[] columnNames;
/**
* Constructs a {@link CompositeFetchOwnerDelegate}.
* @param sessionFactory - the session factory.
* @param compositeType - the composite type.
* @param columnNames - the column names used by sub-attribute fetches.
*/
public CompositeFetchOwnerDelegate( public CompositeFetchOwnerDelegate(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CompositeType compositeType, CompositeType compositeType,

View File

@ -12,7 +12,10 @@ import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
/** /**
* Represents the {@link FetchOwner} for a composite collection index.
*
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner
*/ */
public class CompositeIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex { public class CompositeIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex {
private final CollectionReference collectionReference; private final CollectionReference collectionReference;
@ -20,14 +23,21 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
private final FetchOwnerDelegate fetchOwnerDelegate; private final FetchOwnerDelegate fetchOwnerDelegate;
/**
* Constructs a {@link CompositeElementGraph}.
*
* @param sessionFactory - the session factory.
* @param collectionReference - the collection reference.
* @param collectionPath - the {@link PropertyPath} for the collection.
*/
public CompositeIndexGraph( public CompositeIndexGraph(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference, CollectionReference collectionReference,
PropertyPath propertyPath) { PropertyPath collectionPath) {
super( sessionFactory ); super( sessionFactory );
this.collectionReference = collectionReference; this.collectionReference = collectionReference;
this.collectionPersister = collectionReference.getCollectionPersister(); this.collectionPersister = collectionReference.getCollectionPersister();
this.propertyPath = propertyPath.append( "<index>" ); this.propertyPath = collectionPath.append( "<index>" );
this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate( this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate(
sessionFactory, sessionFactory,
(CompositeType) collectionPersister.getIndexType(), (CompositeType) collectionPersister.getIndexType(),
@ -52,6 +62,7 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
return collectionPersister.getOwnerEntityPersister(); return collectionPersister.getOwnerEntityPersister();
} }
@Override
public CollectionReference getCollectionReference() { public CollectionReference getCollectionReference() {
return collectionReference; return collectionReference;
} }
@ -71,6 +82,7 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
return fetchOwnerDelegate; return fetchOwnerDelegate;
} }
@Override
public CollectionFetch buildCollectionFetch( public CollectionFetch buildCollectionFetch(
AssociationAttributeDefinition attributeDefinition, AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy, FetchStrategy fetchStrategy,

View File

@ -9,6 +9,9 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.AssociationType; import org.hibernate.type.AssociationType;
/** /**
* Represents the {@link FetchOwner} for a collection element that is
* an entity association type.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EntityElementGraph extends AbstractFetchOwner implements FetchableCollectionElement, EntityReference { public class EntityElementGraph extends AbstractFetchOwner implements FetchableCollectionElement, EntityReference {
@ -21,6 +24,13 @@ public class EntityElementGraph extends AbstractFetchOwner implements FetchableC
private IdentifierDescription identifierDescription; private IdentifierDescription identifierDescription;
/**
* Constructs an {@link EntityElementGraph}.
*
* @param sessionFactory - the session factory.
* @param collectionReference - the collection reference.
* @param collectionPath - the {@link PropertyPath} for the collection.
*/
public EntityElementGraph( public EntityElementGraph(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference, CollectionReference collectionReference,

View File

@ -37,28 +37,39 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
/** /**
* Represents a {@link Fetch} for an entity association attribute as well as a
* {@link FetchOwner} of the entity association sub-attribute fetches.
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference, Fetch { public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference, Fetch {
private final EntityType associationType;
private final EntityPersister persister; private final EntityPersister persister;
private final LockMode lockMode; private final LockMode lockMode;
private final FetchOwnerDelegate fetchOwnerDelegate; private final FetchOwnerDelegate fetchOwnerDelegate;
private IdentifierDescription identifierDescription; private IdentifierDescription identifierDescription;
/**
* Constructs an {@link EntityFetch} object.
*
* @param sessionFactory - the session factory.
* @param lockMode - the lock mode.
* @param owner - the fetch owner for this fetch.
* @param ownerProperty - the owner's property referring to this fetch.
* @param fetchStrategy - the fetch strategy for this fetch.
*/
public EntityFetch( public EntityFetch(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
LockMode lockMode, LockMode lockMode,
FetchOwner owner, FetchOwner owner,
String ownerProperty, String ownerProperty,
EntityType entityType,
FetchStrategy fetchStrategy) { FetchStrategy fetchStrategy) {
super( sessionFactory, owner, ownerProperty, fetchStrategy ); super( sessionFactory, owner, ownerProperty, fetchStrategy );
this.associationType = entityType; this.persister = sessionFactory.getEntityPersister(
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() ); getEntityType().getAssociatedEntityName()
);
this.lockMode = lockMode; this.lockMode = lockMode;
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( persister ); this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( persister );
} }
@ -71,14 +82,17 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
*/ */
protected EntityFetch(EntityFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) { protected EntityFetch(EntityFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext, fetchOwnerCopy ); super( original, copyContext, fetchOwnerCopy );
this.associationType = original.associationType;
this.persister = original.persister; this.persister = original.persister;
this.lockMode = original.lockMode; this.lockMode = original.lockMode;
this.fetchOwnerDelegate = original.fetchOwnerDelegate; this.fetchOwnerDelegate = original.fetchOwnerDelegate;
} }
public EntityType getAssociationType() { /**
return associationType; * Returns the entity type for this fetch.
* @return the entity type for this fetch.
*/
public final EntityType getEntityType() {
return (EntityType) getOwner().getType( this );
} }
@Override @Override
@ -134,12 +148,12 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
entityKey = identifierDescription.resolve( resultSet, context ); entityKey = identifierDescription.resolve( resultSet, context );
if ( entityKey == null ) { if ( entityKey == null ) {
// register the non-existence (though only for one-to-one associations) // register the non-existence (though only for one-to-one associations)
if ( associationType.isOneToOne() ) { if ( getEntityType().isOneToOne() ) {
// first, find our owner's entity-key... // first, find our owner's entity-key...
final EntityKey ownersEntityKey = context.getIdentifierResolutionContext( (EntityReference) getOwner() ).getEntityKey(); final EntityKey ownersEntityKey = context.getIdentifierResolutionContext( (EntityReference) getOwner() ).getEntityKey();
if ( ownersEntityKey != null ) { if ( ownersEntityKey != null ) {
context.getSession().getPersistenceContext() context.getSession().getPersistenceContext()
.addNullProperty( ownersEntityKey, associationType.getPropertyName() ); .addNullProperty( ownersEntityKey, getEntityType().getPropertyName() );
} }
} }
} }
@ -154,6 +168,16 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
return entityKey; return entityKey;
} }
/**
* Resolve any fetches required to resolve the identifier as well
* as the entity key for this fetch..
*
* @param resultSet - the result set.
* @param context - the result set processing context.
* @return the entity key for this fetch.
*
* @throws SQLException
*/
public EntityKey resolveInIdentifier(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { public EntityKey resolveInIdentifier(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
// todo : may not need to do this if entitykey is already part of the resolution context // todo : may not need to do this if entitykey is already part of the resolution context
@ -219,7 +243,7 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
acquiredLockMode, acquiredLockMode,
persister, persister,
getFetchStrategy().getTiming() == FetchTiming.IMMEDIATE, getFetchStrategy().getTiming() == FetchTiming.IMMEDIATE,
associationType getEntityType()
); );
// materialize associations (and initialize the object) later // materialize associations (and initialize the object) later

View File

@ -30,11 +30,19 @@ import org.hibernate.type.AssociationType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* This interface provides a delegate for an entity fetch owner to
* obtain details about an owned attribute fetch.
*
* @author Gail Badner * @author Gail Badner
*/ */
public class EntityFetchOwnerDelegate implements FetchOwnerDelegate { public class EntityFetchOwnerDelegate implements FetchOwnerDelegate {
private final EntityPersister entityPersister; private final EntityPersister entityPersister;
/**
* Constructs an {@link EntityFetchOwnerDelegate}.
*
* @param entityPersister - the entity persister.
*/
public EntityFetchOwnerDelegate(EntityPersister entityPersister) { public EntityFetchOwnerDelegate(EntityPersister entityPersister) {
this.entityPersister = entityPersister; this.entityPersister = entityPersister;
} }

View File

@ -32,6 +32,8 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.AssociationType; import org.hibernate.type.AssociationType;
/** /**
* Represents the {@link FetchOwner} for a collection index that is an entity.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex, EntityReference { public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex, EntityReference {
@ -44,6 +46,13 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
private IdentifierDescription identifierDescription; private IdentifierDescription identifierDescription;
/**
* Constructs an {@link EntityIndexGraph}.
*
* @param sessionFactory - the session factory.
* @param collectionReference - the collection reference.
* @param collectionPath - the {@link PropertyPath} for the collection.
*/
public EntityIndexGraph( public EntityIndexGraph(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference, CollectionReference collectionReference,
@ -67,6 +76,9 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
this.fetchOwnerDelegate = original.fetchOwnerDelegate; this.fetchOwnerDelegate = original.fetchOwnerDelegate;
} }
/**
* TODO: Does lock mode apply to a collection index that is an entity?
*/
@Override @Override
public LockMode getLockMode() { public LockMode getLockMode() {
return null; return null;
@ -111,6 +123,11 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
return new EntityIndexGraph( this, copyContext ); return new EntityIndexGraph( this, copyContext );
} }
@Override
public CollectionReference getCollectionReference() {
return collectionReference;
}
@Override @Override
protected FetchOwnerDelegate getFetchOwnerDelegate() { protected FetchOwnerDelegate getFetchOwnerDelegate() {
return fetchOwnerDelegate; return fetchOwnerDelegate;

View File

@ -38,13 +38,18 @@ import org.hibernate.persister.entity.EntityPersister;
import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext; import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext;
/** /**
* Represents an entity return value in the query results. Not the same
* as a result (column) in the JDBC ResultSet!
*
* @see Return
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference, CopyableReturn { public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference, CopyableReturn {
private final EntityPersister persister; private final EntityPersister persister;
private final PropertyPath propertyPath = new PropertyPath(); // its a root private final PropertyPath propertyPath = new PropertyPath(); // it's a root
private final LockMode lockMode; private final LockMode lockMode;
@ -52,6 +57,13 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
private IdentifierDescription identifierDescription; private IdentifierDescription identifierDescription;
/**
* Construct an {@link EntityReturn}.
*
* @param sessionFactory - the session factory.
* @param lockMode - the lock mode.
* @param entityName - the entity name.
*/
public EntityReturn( public EntityReturn(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
LockMode lockMode, LockMode lockMode,

View File

@ -52,10 +52,25 @@ public interface Fetch extends CopyableFetch {
*/ */
public String getOwnerPropertyName(); public String getOwnerPropertyName();
/**
* Is this fetch nullable?
*
* @return true, if this fetch is nullable; false, otherwise.
*/
public boolean isNullable(); public boolean isNullable();
/**
* Gets the column names used for this fetch.
*
* @return the column names used for this fetch.
*/
public String[] getColumnNames(); public String[] getColumnNames();
/**
* Gets the fetch strategy for this fetch.
*
* @return the fetch strategy for this fetch.
*/
public FetchStrategy getFetchStrategy(); public FetchStrategy getFetchStrategy();
/** /**

View File

@ -57,10 +57,31 @@ public interface FetchOwner {
*/ */
public Fetch[] getFetches(); public Fetch[] getFetches();
/**
* Returns the type of the specified fetch.
*
* @param fetch - the owned fetch.
*
* @return the type of the specified fetch.
*/
public Type getType(Fetch fetch); public Type getType(Fetch fetch);
/**
* Is the specified fetch nullable?
*
* @param fetch - the owned fetch.
*
* @return true, if the fetch is nullable; false, otherwise.
*/
public boolean isNullable(Fetch fetch); public boolean isNullable(Fetch fetch);
/**
* Returns the column names used for loading the specified fetch.
*
* @param fetch - the owned fetch.
*
* @return the column names used for loading the specified fetch.
*/
public String[] getColumnNames(Fetch fetch); public String[] getColumnNames(Fetch fetch);
/** /**

View File

@ -26,13 +26,36 @@ package org.hibernate.loader.plan.spi;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* This interface provides a delegate for a fetch owner to obtain details about an owned fetch.
*
* @author Gail Badner * @author Gail Badner
*/ */
public interface FetchOwnerDelegate { public interface FetchOwnerDelegate {
/**
* Is the specified fetch nullable?
*
* @param fetch - the owned fetch.
*
* @return true, if the fetch is nullable; false, otherwise.
*/
public boolean isNullable(Fetch fetch); public boolean isNullable(Fetch fetch);
/**
* Returns the type of the specified fetch.
*
* @param fetch - the owned fetch.
*
* @return the type of the specified fetch.
*/
public Type getType(Fetch fetch); public Type getType(Fetch fetch);
/**
* Returns the column names used for loading the specified fetch.
*
* @param fetch - the owned fetch.
*
* @return the column names used for loading the specified fetch.
*/
public String[] getColumnNames(Fetch fetch); public String[] getColumnNames(Fetch fetch);
} }

View File

@ -23,7 +23,6 @@
*/ */
package org.hibernate.loader.plan.spi; package org.hibernate.loader.plan.spi;
import org.hibernate.persister.collection.CollectionPersister;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -32,5 +31,9 @@ public interface FetchableCollectionElement extends FetchOwner, CopyableReturn {
@Override @Override
public FetchableCollectionElement makeCopy(CopyContext copyContext); public FetchableCollectionElement makeCopy(CopyContext copyContext);
/**
* Returns the collection reference.
* @return the collection reference.
*/
public CollectionReference getCollectionReference(); public CollectionReference getCollectionReference();
} }

View File

@ -31,4 +31,10 @@ package org.hibernate.loader.plan.spi;
public interface FetchableCollectionIndex extends FetchOwner, CopyableReturn { public interface FetchableCollectionIndex extends FetchOwner, CopyableReturn {
@Override @Override
public FetchableCollectionIndex makeCopy(CopyContext copyContext); public FetchableCollectionIndex makeCopy(CopyContext copyContext);
/**
* Returns the collection reference.
* @return the collection reference.
*/
public CollectionReference getCollectionReference();
} }

View File

@ -69,8 +69,8 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition;
import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
import org.hibernate.persister.walking.spi.WalkingException; import org.hibernate.persister.walking.spi.WalkingException;
@ -319,7 +319,7 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
} }
@Override @Override
public void startingCompositeElement(CompositionElementDefinition compositeElementDefinition) { public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
System.out.println( System.out.println(
String.format( String.format(
"%s Starting composite collection element for (%s)", "%s Starting composite collection element for (%s)",
@ -330,7 +330,7 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
} }
@Override @Override
public void finishingCompositeElement(CompositionElementDefinition compositeElementDefinition) { public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
// pop the current fetch owner, and make sure what we just popped represents this composition // pop the current fetch owner, and make sure what we just popped represents this composition
final FetchOwner poppedFetchOwner = popFromStack(); final FetchOwner poppedFetchOwner = popFromStack();

View File

@ -86,8 +86,8 @@ import org.hibernate.persister.walking.spi.AttributeSource;
import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition;
import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.sql.Alias; import org.hibernate.sql.Alias;
@ -2010,15 +2010,13 @@ public abstract class AbstractCollectionPersister
} }
@Override @Override
public CompositionElementDefinition toCompositeElementDefinition() { public CompositeCollectionElementDefinition toCompositeElementDefinition() {
final String propertyName = role.substring( entityName.length() + 1 );
final int propertyIndex = ownerPersister.getEntityMetamodel().getPropertyIndex( propertyName );
if ( ! getType().isComponentType() ) { if ( ! getType().isComponentType() ) {
throw new IllegalStateException( "Cannot treat entity collection element type as composite" ); throw new IllegalStateException( "Cannot treat entity collection element type as composite" );
} }
return new CompositionElementDefinition() { return new CompositeCollectionElementDefinition() {
@Override @Override
public String getName() { public String getName() {
return ""; return "";
@ -2038,7 +2036,7 @@ public abstract class AbstractCollectionPersister
@Override @Override
public Iterable<AttributeDefinition> getAttributes() { public Iterable<AttributeDefinition> getAttributes() {
return CompositionSingularSubAttributesHelper.getCompositionElementSubAttributes( this ); return CompositionSingularSubAttributesHelper.getCompositeCollectionElementSubAttributes( this );
} }
@Override @Override

View File

@ -1,3 +1,26 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.persister.walking.internal; package org.hibernate.persister.walking.internal;
import java.util.Iterator; import java.util.Iterator;
@ -20,8 +43,8 @@ import org.hibernate.persister.walking.spi.AssociationKey;
import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeSource; import org.hibernate.persister.walking.spi.AttributeSource;
import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.persister.walking.spi.WalkingException; import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.AssociationType; import org.hibernate.type.AssociationType;
@ -29,10 +52,22 @@ import org.hibernate.type.CompositeType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* A helper for getting attributes from a composition that is known
* to have only singular attributes; for example, sub-attributes of a
* composite ID or a composite collection element.
*
* TODO: This should be refactored into a delegate and renamed.
*
* @author Gail Badner * @author Gail Badner
*/ */
public class CompositionSingularSubAttributesHelper { public class CompositionSingularSubAttributesHelper {
/**
* Get composite ID sub-attribute definitions.
*
* @param entityPersister - the entity persister.
* @return composite ID sub-attribute definitions.
*/
public static Iterable<AttributeDefinition> getIdentifierSubAttributes( public static Iterable<AttributeDefinition> getIdentifierSubAttributes(
final AbstractEntityPersister entityPersister) { final AbstractEntityPersister entityPersister) {
return getSingularSubAttributes( return getSingularSubAttributes(
@ -44,8 +79,13 @@ public class CompositionSingularSubAttributesHelper {
); );
} }
public static Iterable<AttributeDefinition> getCompositionElementSubAttributes( /**
CompositionElementDefinition compositionElementDefinition) { * Get sub-attribute definitions for a composite collection element.
* @param compositionElementDefinition - composite collection element definition.
* @return sub-attribute definitions for a composite collection element.
*/
public static Iterable<AttributeDefinition> getCompositeCollectionElementSubAttributes(
CompositeCollectionElementDefinition compositionElementDefinition) {
final QueryableCollection collectionPersister = final QueryableCollection collectionPersister =
(QueryableCollection) compositionElementDefinition.getCollectionDefinition().getCollectionPersister(); (QueryableCollection) compositionElementDefinition.getCollectionDefinition().getCollectionPersister();
return getSingularSubAttributes( return getSingularSubAttributes(

View File

@ -55,8 +55,8 @@ public interface AssociationVisitationStrategy {
public void startingComposite(CompositionDefinition compositionDefinition); public void startingComposite(CompositionDefinition compositionDefinition);
public void finishingComposite(CompositionDefinition compositionDefinition); public void finishingComposite(CompositionDefinition compositionDefinition);
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition); public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition); public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
public boolean startingAttribute(AttributeDefinition attributeDefinition); public boolean startingAttribute(AttributeDefinition attributeDefinition);
public void finishingAttribute(AttributeDefinition attributeDefinition); public void finishingAttribute(AttributeDefinition attributeDefinition);

View File

@ -26,14 +26,49 @@ package org.hibernate.persister.walking.spi;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* Represents a collection element.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface CollectionElementDefinition { public interface CollectionElementDefinition {
/**
* Returns the collection definition.
* @return the collection definition.
*/
public CollectionDefinition getCollectionDefinition(); public CollectionDefinition getCollectionDefinition();
/**
* Returns the collection element type.
* @return the collection element type
*/
public Type getType(); public Type getType();
/**
* If the element type returned by {@link #getType()} is an
* {@link org.hibernate.type.EntityType}, then the entity
* definition for the collection element is returned;
* otherwise, IllegalStateException is thrown.
*
* @return the entity definition for the collection element.
*
* @throws IllegalStateException if the collection element type
* returned by {@link #getType()} is not of type
* {@link org.hibernate.type.EntityType}.
*/
public EntityDefinition toEntityDefinition(); public EntityDefinition toEntityDefinition();
public CompositionElementDefinition toCompositeElementDefinition(); /**
* If the element type returned by {@link #getType()} is a
* {@link org.hibernate.type.CompositeType}, then the composite
* element definition for the collection element is returned;
* otherwise, IllegalStateException is thrown.
*
* @return the composite element definition for the collection element.
*
* @throws IllegalStateException if the collection element type
* returned by {@link #getType()} is not of type
* {@link org.hibernate.type.CompositeType}.
*/
public CompositeCollectionElementDefinition toCompositeElementDefinition();
} }

View File

@ -24,8 +24,14 @@
package org.hibernate.persister.walking.spi; package org.hibernate.persister.walking.spi;
/** /**
* The definition for a composite collection element.
*
* @author Gail Badner * @author Gail Badner
*/ */
public interface CompositionElementDefinition extends CompositionDefinition{ public interface CompositeCollectionElementDefinition extends CompositionDefinition{
/**
* Returns the collection definition.
* @return the collection definition.
*/
public CollectionDefinition getCollectionDefinition(); public CollectionDefinition getCollectionDefinition();
} }

View File

@ -202,7 +202,7 @@ public class MetadataDrivenModelGraphVisitor {
strategy.startingCollectionElements( elementDefinition ); strategy.startingCollectionElements( elementDefinition );
if ( elementDefinition.getType().isComponentType() ) { if ( elementDefinition.getType().isComponentType() ) {
visitCompositeElementDefinition( elementDefinition.toCompositeElementDefinition() ); visitCompositeCollectionElementDefinition( elementDefinition.toCompositeElementDefinition() );
} }
else if ( elementDefinition.getType().isEntityType() ) { else if ( elementDefinition.getType().isEntityType() ) {
visitEntityDefinition( elementDefinition.toEntityDefinition() ); visitEntityDefinition( elementDefinition.toEntityDefinition() );
@ -211,12 +211,12 @@ public class MetadataDrivenModelGraphVisitor {
strategy.finishingCollectionElements( elementDefinition ); strategy.finishingCollectionElements( elementDefinition );
} }
private void visitCompositeElementDefinition(CompositionElementDefinition compositionElementDefinition) { private void visitCompositeCollectionElementDefinition(CompositeCollectionElementDefinition compositionElementDefinition) {
strategy.startingCompositeElement( compositionElementDefinition ); strategy.startingCompositeCollectionElement( compositionElementDefinition );
visitAttributes( compositionElementDefinition ); visitAttributes( compositionElementDefinition );
strategy.finishingCompositeElement( compositionElementDefinition ); strategy.finishingCompositeCollectionElement( compositionElementDefinition );
} }
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>(); private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();

View File

@ -30,6 +30,8 @@ import org.hibernate.tuple.NonIdentifierAttribute;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* A base class for a sub-attribute of a composite, non-identifier attribute.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractCompositeBasedAttribute public abstract class AbstractCompositeBasedAttribute

View File

@ -46,6 +46,8 @@ import static org.hibernate.engine.internal.JoinHelper.getLHSTableName;
import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames; import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
/** /**
* A base class for a composite, non-identifier attribute.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractCompositionAttribute extends AbstractNonIdentifierAttribute implements public abstract class AbstractCompositionAttribute extends AbstractNonIdentifierAttribute implements

View File

@ -37,8 +37,8 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition;
import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
@ -170,7 +170,7 @@ public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
} }
@Override @Override
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition) { public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
System.out.println( System.out.println(
String.format( String.format(
"%s Starting composite (%s)", "%s Starting composite (%s)",
@ -181,7 +181,7 @@ public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
} }
@Override @Override
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition) { public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
System.out.println( System.out.println(
String.format( String.format(
"%s Finishing composite (%s)", "%s Finishing composite (%s)",

View File

@ -56,16 +56,11 @@ public class AdviceHelper {
); );
} }
else { else {
EntityType entityType = (EntityType) Helper.resolveType(
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
attributeNode.getAttribute()
);
return new EntityFetch( return new EntityFetch(
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(), (SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
LockMode.NONE, LockMode.NONE,
fetchOwner, fetchOwner,
attributeNode.getAttributeName(), attributeNode.getAttributeName(),
entityType,
new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.SELECT ) new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.SELECT )
); );
} }