HHH-8722 HHH-8723 : Reorg AbstractLoadPlanBuildingAssociationVisitationStrategy and add Any support

This commit is contained in:
Gail Badner 2013-11-19 14:16:31 -08:00
parent ec348c32fd
commit 7693826b77
17 changed files with 184 additions and 81 deletions

View File

@ -197,7 +197,7 @@ public abstract class AbstractEntityGraphVisitationStrategy
@Override
protected boolean handleCompositeAttribute(
final CompositionDefinition attributeDefinition) {
final AttributeDefinition attributeDefinition) {
return super.handleCompositeAttribute( attributeDefinition );
}

View File

@ -89,14 +89,13 @@ public abstract class AbstractCompositeFetch extends AbstractExpandingFetchSourc
}
protected CompositeFetch createCompositeFetch(
CompositionDefinition compositionDefinition,
AttributeDefinition attributeDefinition,
ExpandingCompositeQuerySpace compositeQuerySpace) {
return new NestedCompositeFetchImpl(
this,
compositionDefinition.getType(),
attributeDefinition,
compositeQuerySpace,
allowCollectionFetches,
getPropertyPath().append( compositionDefinition.getName() )
allowCollectionFetches
);
}

View File

@ -30,6 +30,7 @@ import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.EntityIdentifierDescription;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.EncapsulatedEntityIdentifierDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
@ -114,14 +115,13 @@ public abstract class AbstractEntityReference extends AbstractExpandingFetchSour
}
protected CompositeFetch createCompositeFetch(
CompositionDefinition compositionDefinition,
AttributeDefinition attributeDefinition,
ExpandingCompositeQuerySpace compositeQuerySpace) {
return new CompositeFetchImpl(
this,
compositionDefinition.getType(),
attributeDefinition,
compositeQuerySpace,
true,
getPropertyPath().append( compositionDefinition.getName() )
true
);
}
}

View File

@ -27,8 +27,6 @@ import java.util.ArrayList;
import java.util.List;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.internal.spaces.QuerySpaceHelper;
import org.hibernate.loader.plan2.build.spi.ExpandingCollectionQuerySpace;
@ -46,7 +44,7 @@ import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.EntityType;
@ -158,7 +156,7 @@ public abstract class AbstractExpandingFetchSource implements ExpandingFetchSour
}
protected abstract CompositeFetch createCompositeFetch(
CompositionDefinition compositeType,
AttributeDefinition compositeType,
ExpandingCompositeQuerySpace compositeQuerySpace);
protected ExpandingQuerySpaces getQuerySpaces() {
@ -167,7 +165,7 @@ public abstract class AbstractExpandingFetchSource implements ExpandingFetchSour
@Override
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition) {
AttributeDefinition attributeDefinition) {
final ExpandingCompositeQuerySpace compositeQuerySpace = QuerySpaceHelper.INSTANCE.makeCompositeQuerySpace(
expandingQuerySpace(),
attributeDefinition,

View File

@ -31,6 +31,7 @@ import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.type.AnyType;
/**
@ -122,4 +123,9 @@ public class AnyFetchImpl implements AnyFetch {
public EntityReference resolveEntityReference() {
return fetchSource.resolveEntityReference();
}
@Override
public AttributeDefinition getFetchedAttributeDefinition() {
return fetchedAttribute;
}
}

View File

@ -180,4 +180,9 @@ public class CollectionFetchImpl extends AbstractCollectionReference implements
// private EntityReference findOwnerEntityReference(FetchOwner owner) {
// return Helper.INSTANCE.findOwnerEntityReference( owner );
// }
@Override
public AttributeDefinition getFetchedAttributeDefinition() {
return fetchedAttribute;
}
}

View File

@ -23,30 +23,41 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.CompositeAttributeFetch;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.type.CompositeType;
/**
* @author Steve Ebersole
*/
public class CompositeFetchImpl extends AbstractCompositeFetch implements CompositeFetch {
public class CompositeFetchImpl extends AbstractCompositeFetch implements CompositeAttributeFetch {
private final FetchSource source;
private final AttributeDefinition fetchedAttribute;
protected CompositeFetchImpl(
FetchSource source,
CompositeType compositeType,
AttributeDefinition attributeDefinition,
ExpandingCompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches,
PropertyPath propertyPath) {
super( compositeType, compositeQuerySpace, allowCollectionFetches, propertyPath );
boolean allowCollectionFetches) {
super(
(CompositeType) attributeDefinition.getType(),
compositeQuerySpace,
allowCollectionFetches,
source.getPropertyPath().append( attributeDefinition.getName() )
);
this.source = source;
this.fetchedAttribute = attributeDefinition;
}
@Override
public FetchSource getSource() {
return source;
}
@Override
public AttributeDefinition getFetchedAttributeDefinition() {
return fetchedAttribute;
}
}

View File

@ -92,4 +92,9 @@ public class EntityFetchImpl extends AbstractEntityReference implements EntityFe
// those do cause problems in Loader; question is whether those are indicative of that situation or
// of Loaders ability to handle it.
}
@Override
public AttributeDefinition getFetchedAttributeDefinition() {
return fetchedAttribute;
}
}

View File

@ -23,29 +23,42 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CompositeAttributeFetch;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.type.CompositeType;
/**
* @author Steve Ebersole
*/
public class NestedCompositeFetchImpl extends AbstractCompositeFetch {
public class NestedCompositeFetchImpl extends AbstractCompositeFetch implements CompositeAttributeFetch {
private final CompositeFetch source;
private final AttributeDefinition fetchedAttributeDefinition;
public NestedCompositeFetchImpl(
CompositeFetch source,
CompositeType type,
AttributeDefinition fetchedAttributeDefinition,
ExpandingCompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches, PropertyPath propertyPath) {
super( type, compositeQuerySpace, allowCollectionFetches, propertyPath );
boolean allowCollectionFetches) {
super(
(CompositeType) fetchedAttributeDefinition.getType(),
compositeQuerySpace,
allowCollectionFetches,
source.getPropertyPath().append( fetchedAttributeDefinition.getName() )
);
this.source = source;
this.fetchedAttributeDefinition = fetchedAttributeDefinition;
}
@Override
public FetchSource getSource() {
return source;
}
@Override
public AttributeDefinition getFetchedAttributeDefinition() {
return fetchedAttributeDefinition;
}
}

View File

@ -35,6 +35,7 @@ import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.CollectionType;
@ -117,26 +118,25 @@ public class QuerySpaceHelper {
public ExpandingCompositeQuerySpace makeCompositeQuerySpace(
ExpandingQuerySpace lhsQuerySpace,
CompositionDefinition compositionDefinition,
AttributeDefinition attributeDefinition,
String querySpaceUid,
boolean shouldIncludeJoin) {
final boolean required = lhsQuerySpace.canJoinsBeRequired() && !compositionDefinition.isNullable();
final boolean required = lhsQuerySpace.canJoinsBeRequired() && !attributeDefinition.isNullable();
return makeCompositeQuerySpace(
lhsQuerySpace,
new CompositePropertyMapping(
compositionDefinition.getType(),
(CompositeType) attributeDefinition.getType(),
lhsQuerySpace.getPropertyMapping(),
compositionDefinition.getName()
attributeDefinition.getName()
),
compositionDefinition.getName(),
compositionDefinition.getType(),
attributeDefinition.getName(),
(CompositeType) attributeDefinition.getType(),
querySpaceUid,
required,
shouldIncludeJoin
);
}
public ExpandingCompositeQuerySpace makeCompositeQuerySpace(
ExpandingQuerySpace lhsQuerySpace,
CompositePropertyMapping compositePropertyMapping,

View File

@ -25,9 +25,7 @@ package org.hibernate.loader.plan2.build.spi;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jboss.logging.Logger;
import org.jboss.logging.MDC;
@ -42,11 +40,13 @@ import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.internal.spaces.QuerySpacesImpl;
import org.hibernate.loader.plan2.build.internal.returns.CollectionReturnImpl;
import org.hibernate.loader.plan2.build.internal.returns.EntityReturnImpl;
import org.hibernate.loader.plan2.spi.AttributeFetch;
import org.hibernate.loader.plan2.spi.CollectionFetch;
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
import org.hibernate.loader.plan2.spi.CollectionReference;
import org.hibernate.loader.plan2.spi.CollectionReturn;
import org.hibernate.loader.plan2.spi.CompositeAttributeFetch;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.EntityIdentifierDescription;
@ -93,8 +93,6 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
private final ArrayDeque<ExpandingFetchSource> fetchSourceStack = new ArrayDeque<ExpandingFetchSource>();
private final Set<AttributeDefinition> pushedAttributes = new HashSet<AttributeDefinition>( );
protected AbstractLoadPlanBuildingAssociationVisitationStrategy(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
this.querySpaces = new QuerySpacesImpl( sessionFactory );
@ -155,7 +153,6 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
propertyPathStack.pop();
MDC.remove( MDC_KEY );
fetchSourceStack.clear();
pushedAttributes.clear();
}
@ -586,50 +583,58 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
return handleAssociationAttribute( (AssociationAttributeDefinition) attributeDefinition );
}
else {
return handleCompositeAttribute( (CompositionDefinition) attributeDefinition );
return handleCompositeAttribute( attributeDefinition );
}
}
@Override
public void finishingAttribute(AttributeDefinition attributeDefinition) {
if ( pushedAttributes.contains( attributeDefinition ) ) {
final Type attributeType = attributeDefinition.getType();
if ( attributeType.isComponentType() ) {
// pop the current fetch owner, and make sure what we just popped represents this composition
final ExpandingFetchSource popped = popFromStack();
if ( ! CompositeFetch.class.isInstance( popped ) ) {
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
}
}
else if ( attributeType.isAssociationType() ) {
final AssociationAttributeDefinition associationAttributeDefinition =
(AssociationAttributeDefinition) attributeDefinition;
if ( attributeType.isCollectionType() ) {
popFromCollectionStack( associationAttributeDefinition.toCollectionDefinition() );
}
else if ( attributeType.isEntityType() ) {
popEntityFromStack( associationAttributeDefinition.toEntityDefinition() );
}
else {
throw new WalkingException(
String.format(
"Unexpected attribute of type [%s] was pushed: %s",
associationAttributeDefinition.getType(),
associationAttributeDefinition
)
);
}
}
else {
final Type attributeType = attributeDefinition.getType();
if ( attributeType.isAnyType() ) {
// If attributeType.isAnyType() is true, then attributeType.isComponentType() and
// attributeType.isAssociationType() will also be true, so need to
// check attributeType.isAnyType() first.
// Nothing to do because AnyFetch does not implement ExpandingFetchSource (i.e., it cannot be pushed/popped).
}
else if ( attributeType.isComponentType() ) {
// CompositeFetch is always pushed, during #startingAttribute(),
// so pop the current fetch owner, and make sure what we just popped represents this composition
final ExpandingFetchSource popped = popFromStack();
if ( !CompositeAttributeFetch.class.isInstance( popped ) ) {
throw new WalkingException(
String.format(
"Unexpected attribute of type [%s] was pushed: %s",
attributeDefinition.getType(),
attributeDefinition
"Mismatched FetchSource from stack on pop; expected: CompositeAttributeFetch; actual: [%s]",
popped
)
);
}
pushedAttributes.remove( attributeDefinition );
final CompositeAttributeFetch poppedAsCompositeAttributeFetch = (CompositeAttributeFetch) popped;
if ( !attributeDefinition.equals( poppedAsCompositeAttributeFetch.getFetchedAttributeDefinition() ) ) {
throw new WalkingException(
String.format(
"Mismatched CompositeAttributeFetch from stack on pop; expected fetch for attribute: [%s]; actual: [%s]",
attributeDefinition,
poppedAsCompositeAttributeFetch.getFetchedAttributeDefinition()
)
);
}
}
else if ( attributeType.isEntityType() ) {
final ExpandingFetchSource source = currentSource();
if ( AttributeFetch.class.isInstance( source ) &&
attributeDefinition.equals( AttributeFetch.class.cast( source ).getFetchedAttributeDefinition() ) ) {
popEntityFromStack( ( (AssociationAttributeDefinition) attributeDefinition ).toEntityDefinition() );
}
}
else if ( attributeType.isCollectionType() ) {
final CollectionReference currentCollection = collectionReferenceStack.peekFirst();
if ( currentCollection != null &&
AttributeFetch.class.isInstance( currentCollection ) &&
attributeDefinition.equals( AttributeFetch.class.cast( currentCollection ).getFetchedAttributeDefinition() ) ) {
popFromCollectionStack( ( (AssociationAttributeDefinition) attributeDefinition ).toCollectionDefinition() );
}
}
log.tracef(
@ -856,10 +861,9 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
return false;
}
protected boolean handleCompositeAttribute(CompositionDefinition attributeDefinition) {
protected boolean handleCompositeAttribute(AttributeDefinition attributeDefinition) {
final CompositeFetch compositeFetch = currentSource().buildCompositeFetch( attributeDefinition );
pushToStack( (ExpandingFetchSource) compositeFetch );
pushedAttributes.add( attributeDefinition );
return true;
}
@ -888,7 +892,6 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
);
if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) {
pushToStack( (ExpandingFetchSource) fetch );
pushedAttributes.add( attributeDefinition );
return true;
}
else {
@ -900,7 +903,6 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
CollectionFetch fetch = currentSource.buildCollectionFetch( attributeDefinition, fetchStrategy );
if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) {
pushToCollectionStack( fetch );
pushedAttributes.add( attributeDefinition );
return true;
}
else {

View File

@ -33,7 +33,6 @@ import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
/**
* Describes the internal contract for things which can contain fetches. Used to request building
@ -60,7 +59,7 @@ public interface ExpandingFetchSource extends FetchSource {
EntityReference targetEntityReference);
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition);
AttributeDefinition attributeDefinition);
public CollectionFetch buildCollectionFetch(
AssociationAttributeDefinition attributeDefinition,

View File

@ -26,5 +26,5 @@ package org.hibernate.loader.plan2.spi;
/**
* @author Gail Badner
*/
public interface AnyFetch extends Fetch, FetchSource {
public interface AnyFetch extends AttributeFetch, FetchSource {
}

View File

@ -0,0 +1,35 @@
/*
* 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.loader.plan2.spi;
import org.hibernate.persister.walking.spi.AttributeDefinition;
/**
* Models a {@link Fetch} that is specifically for an attribute.
*
* @author Gail Badner
*/
public interface AttributeFetch extends Fetch {
public AttributeDefinition getFetchedAttributeDefinition();
}

View File

@ -30,7 +30,7 @@ import org.hibernate.type.CollectionType;
*
* @author Steve Ebersole
*/
public interface CollectionFetch extends Fetch, CollectionReference {
public interface CollectionFetch extends AttributeFetch, CollectionReference {
@Override
public CollectionType getFetchedType();

View File

@ -0,0 +1,30 @@
/*
* 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.loader.plan2.spi;
/**
* @author Gail Badner
*/
public interface CompositeAttributeFetch extends CompositeFetch, AttributeFetch {
}

View File

@ -28,7 +28,7 @@ import org.hibernate.type.EntityType;
/**
* @author Steve Ebersole
*/
public interface EntityFetch extends Fetch, EntityReference {
public interface EntityFetch extends AttributeFetch, EntityReference {
@Override
EntityType getFetchedType();
}