HHH-7841 - Redesign Loader
This commit is contained in:
parent
a03d44f290
commit
b846fa35b5
|
@ -58,7 +58,7 @@ public class EntityJoinableAssociationImpl extends AbstractJoinableAssociationIm
|
|||
hasRestriction,
|
||||
enabledFilters
|
||||
);
|
||||
this.joinableType = entityFetch.getAssociationType();
|
||||
this.joinableType = entityFetch.getEntityType();
|
||||
this.joinable = (Joinable) entityFetch.getEntityPersister();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ public class LoadPlanBuildingHelper {
|
|||
LockMode.NONE, // todo : for now
|
||||
fetchOwner,
|
||||
attributeDefinition.getName(),
|
||||
(EntityType) attributeDefinition.getType(),
|
||||
fetchStrategy
|
||||
);
|
||||
}
|
||||
|
|
|
@ -36,11 +36,17 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
|
|||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* This is a class for fetch owners, providing functionality related to the owned
|
||||
* fetches.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
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;
|
||||
|
||||
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.
|
||||
*
|
||||
* @param original - the original object to copy.
|
||||
* @param copyContext - the copy context.
|
||||
*/
|
||||
protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) {
|
||||
super( original );
|
||||
validate();
|
||||
|
||||
// TODO: I don't think this is correct; shouldn't the fetches from original be copied into this???
|
||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
||||
if ( fetches == null || fetches.size() == 0 ) {
|
||||
this.fetches = Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
// TODO: don't think this is correct...
|
||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
||||
for ( Fetch fetch : fetches ) {
|
||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
||||
|
@ -75,6 +82,7 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
|
|||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFetch(Fetch fetch) {
|
||||
if ( fetch.getOwner() != this ) {
|
||||
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() ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method returning the delegate for obtaining details about an owned fetch.
|
||||
* @return the delegate
|
||||
*/
|
||||
protected abstract FetchOwnerDelegate getFetchOwnerDelegate();
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,7 +30,10 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.loader.PropertyPath;
|
||||
|
||||
/**
|
||||
* Represents a singular attribute that is both a {@link FetchOwner} and a {@link Fetch}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner implements Fetch {
|
||||
private final FetchOwner owner;
|
||||
|
@ -39,6 +42,14 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
|
|||
|
||||
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(
|
||||
SessionFactoryImplementor factory,
|
||||
FetchOwner owner,
|
||||
|
|
|
@ -12,7 +12,10 @@ import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
* Represents the {@link FetchOwner} for a composite collection element.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class CompositeElementGraph extends AbstractFetchOwner implements FetchableCollectionElement {
|
||||
private final CollectionReference collectionReference;
|
||||
|
@ -20,6 +23,13 @@ public class CompositeElementGraph extends AbstractFetchOwner implements Fetchab
|
|||
private final CollectionPersister collectionPersister;
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
CollectionReference collectionReference,
|
||||
|
|
|
@ -29,22 +29,29 @@ import org.hibernate.engine.FetchStrategy;
|
|||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
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.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||
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 Gail Badner
|
||||
*/
|
||||
public class CompositeFetch extends AbstractSingularAttributeFetch {
|
||||
public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
FetchOwner owner,
|
||||
|
@ -72,33 +79,6 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
|
|||
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
|
||||
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
|
|
|
@ -32,6 +32,9 @@ import org.hibernate.type.CompositeType;
|
|||
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
|
||||
*/
|
||||
public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate {
|
||||
|
@ -39,6 +42,12 @@ public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate {
|
|||
private final CompositeType compositeType;
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
CompositeType compositeType,
|
||||
|
|
|
@ -12,7 +12,10 @@ import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
* Represents the {@link FetchOwner} for a composite collection index.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class CompositeIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex {
|
||||
private final CollectionReference collectionReference;
|
||||
|
@ -20,14 +23,21 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
|
|||
private final CollectionPersister collectionPersister;
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
CollectionReference collectionReference,
|
||||
PropertyPath propertyPath) {
|
||||
PropertyPath collectionPath) {
|
||||
super( sessionFactory );
|
||||
this.collectionReference = collectionReference;
|
||||
this.collectionPersister = collectionReference.getCollectionPersister();
|
||||
this.propertyPath = propertyPath.append( "<index>" );
|
||||
this.propertyPath = collectionPath.append( "<index>" );
|
||||
this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate(
|
||||
sessionFactory,
|
||||
(CompositeType) collectionPersister.getIndexType(),
|
||||
|
@ -52,6 +62,7 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
|
|||
return collectionPersister.getOwnerEntityPersister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionReference getCollectionReference() {
|
||||
return collectionReference;
|
||||
}
|
||||
|
@ -71,6 +82,7 @@ public class CompositeIndexGraph extends AbstractFetchOwner implements Fetchable
|
|||
return fetchOwnerDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionFetch buildCollectionFetch(
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy,
|
||||
|
|
|
@ -9,6 +9,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* Represents the {@link FetchOwner} for a collection element that is
|
||||
* an entity association type.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityElementGraph extends AbstractFetchOwner implements FetchableCollectionElement, EntityReference {
|
||||
|
@ -21,6 +24,13 @@ public class EntityElementGraph extends AbstractFetchOwner implements FetchableC
|
|||
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
CollectionReference collectionReference,
|
||||
|
|
|
@ -37,28 +37,39 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
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
|
||||
*/
|
||||
public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference, Fetch {
|
||||
|
||||
private final EntityType associationType;
|
||||
private final EntityPersister persister;
|
||||
private final LockMode lockMode;
|
||||
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
LockMode lockMode,
|
||||
FetchOwner owner,
|
||||
String ownerProperty,
|
||||
EntityType entityType,
|
||||
FetchStrategy fetchStrategy) {
|
||||
super( sessionFactory, owner, ownerProperty, fetchStrategy );
|
||||
|
||||
this.associationType = entityType;
|
||||
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() );
|
||||
this.persister = sessionFactory.getEntityPersister(
|
||||
getEntityType().getAssociatedEntityName()
|
||||
);
|
||||
this.lockMode = lockMode;
|
||||
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( persister );
|
||||
}
|
||||
|
@ -71,14 +82,17 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
|||
*/
|
||||
protected EntityFetch(EntityFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
|
||||
super( original, copyContext, fetchOwnerCopy );
|
||||
this.associationType = original.associationType;
|
||||
this.persister = original.persister;
|
||||
this.lockMode = original.lockMode;
|
||||
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
|
||||
|
@ -134,12 +148,12 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
|||
entityKey = identifierDescription.resolve( resultSet, context );
|
||||
if ( entityKey == null ) {
|
||||
// register the non-existence (though only for one-to-one associations)
|
||||
if ( associationType.isOneToOne() ) {
|
||||
if ( getEntityType().isOneToOne() ) {
|
||||
// first, find our owner's entity-key...
|
||||
final EntityKey ownersEntityKey = context.getIdentifierResolutionContext( (EntityReference) getOwner() ).getEntityKey();
|
||||
if ( ownersEntityKey != null ) {
|
||||
context.getSession().getPersistenceContext()
|
||||
.addNullProperty( ownersEntityKey, associationType.getPropertyName() );
|
||||
.addNullProperty( ownersEntityKey, getEntityType().getPropertyName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +168,16 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
|||
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 {
|
||||
// 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,
|
||||
persister,
|
||||
getFetchStrategy().getTiming() == FetchTiming.IMMEDIATE,
|
||||
associationType
|
||||
getEntityType()
|
||||
);
|
||||
|
||||
// materialize associations (and initialize the object) later
|
||||
|
|
|
@ -30,11 +30,19 @@ import org.hibernate.type.AssociationType;
|
|||
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
|
||||
*/
|
||||
public class EntityFetchOwnerDelegate implements FetchOwnerDelegate {
|
||||
private final EntityPersister entityPersister;
|
||||
|
||||
/**
|
||||
* Constructs an {@link EntityFetchOwnerDelegate}.
|
||||
*
|
||||
* @param entityPersister - the entity persister.
|
||||
*/
|
||||
public EntityFetchOwnerDelegate(EntityPersister entityPersister) {
|
||||
this.entityPersister = entityPersister;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* Represents the {@link FetchOwner} for a collection index that is an entity.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex, EntityReference {
|
||||
|
@ -44,6 +46,13 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
|
|||
|
||||
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(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
CollectionReference collectionReference,
|
||||
|
@ -67,6 +76,9 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
|
|||
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Does lock mode apply to a collection index that is an entity?
|
||||
*/
|
||||
@Override
|
||||
public LockMode getLockMode() {
|
||||
return null;
|
||||
|
@ -111,6 +123,11 @@ public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCol
|
|||
return new EntityIndexGraph( this, copyContext );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionReference getCollectionReference() {
|
||||
return collectionReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||
return fetchOwnerDelegate;
|
||||
|
|
|
@ -38,13 +38,18 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
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
|
||||
*/
|
||||
public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference, CopyableReturn {
|
||||
|
||||
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;
|
||||
|
||||
|
@ -52,6 +57,13 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
|
|||
|
||||
private IdentifierDescription identifierDescription;
|
||||
|
||||
/**
|
||||
* Construct an {@link EntityReturn}.
|
||||
*
|
||||
* @param sessionFactory - the session factory.
|
||||
* @param lockMode - the lock mode.
|
||||
* @param entityName - the entity name.
|
||||
*/
|
||||
public EntityReturn(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
LockMode lockMode,
|
||||
|
|
|
@ -52,10 +52,25 @@ public interface Fetch extends CopyableFetch {
|
|||
*/
|
||||
public String getOwnerPropertyName();
|
||||
|
||||
/**
|
||||
* Is this fetch nullable?
|
||||
*
|
||||
* @return true, if this fetch is nullable; false, otherwise.
|
||||
*/
|
||||
public boolean isNullable();
|
||||
|
||||
/**
|
||||
* Gets the column names used for this fetch.
|
||||
*
|
||||
* @return the column names used for this fetch.
|
||||
*/
|
||||
public String[] getColumnNames();
|
||||
|
||||
/**
|
||||
* Gets the fetch strategy for this fetch.
|
||||
*
|
||||
* @return the fetch strategy for this fetch.
|
||||
*/
|
||||
public FetchStrategy getFetchStrategy();
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,10 +57,31 @@ public interface FetchOwner {
|
|||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Is the specified fetch nullable?
|
||||
*
|
||||
* @param fetch - the owned fetch.
|
||||
*
|
||||
* @return true, if the fetch is nullable; false, otherwise.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,13 +26,36 @@ package org.hibernate.loader.plan.spi;
|
|||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* This interface provides a delegate for a fetch owner to obtain details about an owned fetch.
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Returns the type of the specified fetch.
|
||||
*
|
||||
* @param fetch - the owned fetch.
|
||||
*
|
||||
* @return the type of the specified 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);
|
||||
}
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -32,5 +31,9 @@ public interface FetchableCollectionElement extends FetchOwner, CopyableReturn {
|
|||
@Override
|
||||
public FetchableCollectionElement makeCopy(CopyContext copyContext);
|
||||
|
||||
/**
|
||||
* Returns the collection reference.
|
||||
* @return the collection reference.
|
||||
*/
|
||||
public CollectionReference getCollectionReference();
|
||||
}
|
||||
|
|
|
@ -31,4 +31,10 @@ package org.hibernate.loader.plan.spi;
|
|||
public interface FetchableCollectionIndex extends FetchOwner, CopyableReturn {
|
||||
@Override
|
||||
public FetchableCollectionIndex makeCopy(CopyContext copyContext);
|
||||
|
||||
/**
|
||||
* Returns the collection reference.
|
||||
* @return the collection reference.
|
||||
*/
|
||||
public CollectionReference getCollectionReference();
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
|
|||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
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.CompositionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||
import org.hibernate.persister.walking.spi.WalkingException;
|
||||
|
@ -319,7 +319,7 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
|||
}
|
||||
|
||||
@Override
|
||||
public void startingCompositeElement(CompositionElementDefinition compositeElementDefinition) {
|
||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Starting composite collection element for (%s)",
|
||||
|
@ -330,7 +330,7 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
|||
}
|
||||
|
||||
@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
|
||||
final FetchOwner poppedFetchOwner = popFromStack();
|
||||
|
||||
|
|
|
@ -86,8 +86,8 @@ import org.hibernate.persister.walking.spi.AttributeSource;
|
|||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
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.CompositionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.sql.Alias;
|
||||
|
@ -2010,15 +2010,13 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompositionElementDefinition toCompositeElementDefinition() {
|
||||
final String propertyName = role.substring( entityName.length() + 1 );
|
||||
final int propertyIndex = ownerPersister.getEntityMetamodel().getPropertyIndex( propertyName );
|
||||
public CompositeCollectionElementDefinition toCompositeElementDefinition() {
|
||||
|
||||
if ( ! getType().isComponentType() ) {
|
||||
throw new IllegalStateException( "Cannot treat entity collection element type as composite" );
|
||||
}
|
||||
|
||||
return new CompositionElementDefinition() {
|
||||
return new CompositeCollectionElementDefinition() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "";
|
||||
|
@ -2038,7 +2036,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getAttributes() {
|
||||
return CompositionSingularSubAttributesHelper.getCompositionElementSubAttributes( this );
|
||||
return CompositionSingularSubAttributesHelper.getCompositeCollectionElementSubAttributes( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
|
||||
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.AttributeSource;
|
||||
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.CompositionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.persister.walking.spi.WalkingException;
|
||||
import org.hibernate.type.AssociationType;
|
||||
|
@ -29,10 +52,22 @@ import org.hibernate.type.CompositeType;
|
|||
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
|
||||
*/
|
||||
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(
|
||||
final AbstractEntityPersister entityPersister) {
|
||||
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 =
|
||||
(QueryableCollection) compositionElementDefinition.getCollectionDefinition().getCollectionPersister();
|
||||
return getSingularSubAttributes(
|
||||
|
|
|
@ -55,8 +55,8 @@ public interface AssociationVisitationStrategy {
|
|||
public void startingComposite(CompositionDefinition compositionDefinition);
|
||||
public void finishingComposite(CompositionDefinition compositionDefinition);
|
||||
|
||||
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition);
|
||||
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition);
|
||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
||||
|
||||
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
||||
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
||||
|
|
|
@ -26,14 +26,49 @@ package org.hibernate.persister.walking.spi;
|
|||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a collection element.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CollectionElementDefinition {
|
||||
|
||||
/**
|
||||
* Returns the collection definition.
|
||||
* @return the collection definition.
|
||||
*/
|
||||
public CollectionDefinition getCollectionDefinition();
|
||||
|
||||
/**
|
||||
* Returns the collection element type.
|
||||
* @return the collection element type
|
||||
*/
|
||||
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 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();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,14 @@
|
|||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
/**
|
||||
* The definition for a composite collection element.
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public interface CompositionElementDefinition extends CompositionDefinition{
|
||||
public interface CompositeCollectionElementDefinition extends CompositionDefinition{
|
||||
/**
|
||||
* Returns the collection definition.
|
||||
* @return the collection definition.
|
||||
*/
|
||||
public CollectionDefinition getCollectionDefinition();
|
||||
}
|
|
@ -202,7 +202,7 @@ public class MetadataDrivenModelGraphVisitor {
|
|||
strategy.startingCollectionElements( elementDefinition );
|
||||
|
||||
if ( elementDefinition.getType().isComponentType() ) {
|
||||
visitCompositeElementDefinition( elementDefinition.toCompositeElementDefinition() );
|
||||
visitCompositeCollectionElementDefinition( elementDefinition.toCompositeElementDefinition() );
|
||||
}
|
||||
else if ( elementDefinition.getType().isEntityType() ) {
|
||||
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
||||
|
@ -211,12 +211,12 @@ public class MetadataDrivenModelGraphVisitor {
|
|||
strategy.finishingCollectionElements( elementDefinition );
|
||||
}
|
||||
|
||||
private void visitCompositeElementDefinition(CompositionElementDefinition compositionElementDefinition) {
|
||||
strategy.startingCompositeElement( compositionElementDefinition );
|
||||
private void visitCompositeCollectionElementDefinition(CompositeCollectionElementDefinition compositionElementDefinition) {
|
||||
strategy.startingCompositeCollectionElement( compositionElementDefinition );
|
||||
|
||||
visitAttributes( compositionElementDefinition );
|
||||
|
||||
strategy.finishingCompositeElement( compositionElementDefinition );
|
||||
strategy.finishingCompositeCollectionElement( compositionElementDefinition );
|
||||
}
|
||||
|
||||
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
||||
|
|
|
@ -30,6 +30,8 @@ import org.hibernate.tuple.NonIdentifierAttribute;
|
|||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* A base class for a sub-attribute of a composite, non-identifier attribute.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractCompositeBasedAttribute
|
||||
|
|
|
@ -46,6 +46,8 @@ import static org.hibernate.engine.internal.JoinHelper.getLHSTableName;
|
|||
import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
|
||||
|
||||
/**
|
||||
* A base class for a composite, non-identifier attribute.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractCompositionAttribute extends AbstractNonIdentifierAttribute implements
|
||||
|
|
|
@ -37,8 +37,8 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
|
|||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
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.CompositionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
|
||||
|
@ -170,7 +170,7 @@ public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition) {
|
||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Starting composite (%s)",
|
||||
|
@ -181,7 +181,7 @@ public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition) {
|
||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Finishing composite (%s)",
|
||||
|
|
|
@ -56,16 +56,11 @@ public class AdviceHelper {
|
|||
);
|
||||
}
|
||||
else {
|
||||
EntityType entityType = (EntityType) Helper.resolveType(
|
||||
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
|
||||
attributeNode.getAttribute()
|
||||
);
|
||||
return new EntityFetch(
|
||||
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
|
||||
LockMode.NONE,
|
||||
fetchOwner,
|
||||
attributeNode.getAttributeName(),
|
||||
entityType,
|
||||
new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.SELECT )
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue