From ec348c32fde4a035752bff2536c893c277c0d18c Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Mon, 18 Nov 2013 22:42:03 -0800 Subject: [PATCH] HHH-8722 HHH-8723 : Reorg AbstractLoadPlanBuildingAssociationVisitationStrategy and add Any support --- .../returns/AbstractExpandingFetchSource.java | 15 +++ .../build/internal/returns/AnyFetchImpl.java | 125 ++++++++++++++++++ ...BuildingAssociationVisitationStrategy.java | 27 +++- .../plan2/build/spi/ExpandingFetchSource.java | 5 + .../hibernate/loader/plan2/spi/AnyFetch.java | 30 +++++ 5 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AnyFetchImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan2/spi/AnyFetch.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractExpandingFetchSource.java b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractExpandingFetchSource.java index ed0613b04d..4a12c209c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractExpandingFetchSource.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractExpandingFetchSource.java @@ -37,6 +37,7 @@ import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace; import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource; import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace; import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpaces; +import org.hibernate.loader.plan2.spi.AnyFetch; import org.hibernate.loader.plan2.spi.BidirectionalEntityReference; import org.hibernate.loader.plan2.spi.CollectionFetch; import org.hibernate.loader.plan2.spi.CompositeFetch; @@ -200,4 +201,18 @@ public abstract class AbstractExpandingFetchSource implements ExpandingFetchSour addFetch( fetch ); return fetch; } + + @Override + public AnyFetch buildAnyFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy) { + + final AnyFetch fetch = new AnyFetchImpl( + this, + attributeDefinition, + fetchStrategy + ); + addFetch( fetch ); + return fetch; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AnyFetchImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AnyFetchImpl.java new file mode 100644 index 0000000000..1d2fa421c0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AnyFetchImpl.java @@ -0,0 +1,125 @@ +/* + * 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.build.internal.returns; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan2.spi.AnyFetch; +import org.hibernate.loader.plan2.spi.BidirectionalEntityReference; +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.type.AnyType; + +/** + * @author Steve Ebersole + * @author Gail Badner + */ +public class AnyFetchImpl implements AnyFetch { + /** + * Convenient constant for returning no fetches from {@link #getFetches()} + */ + private static final Fetch[] NO_FETCHES = new Fetch[0]; + + /** + * Convenient constant for returning no fetches from {@link #getFetches()} + */ + private static final BidirectionalEntityReference[] NO_BIDIRECTIONAL_ENTITY_REFERENCES = + new BidirectionalEntityReference[0]; + + + private final FetchSource fetchSource; + private final AssociationAttributeDefinition fetchedAttribute; + private final FetchStrategy fetchStrategy; + + private final PropertyPath propertyPath; + + public AnyFetchImpl( + FetchSource fetchSource, + AssociationAttributeDefinition fetchedAttribute, + FetchStrategy fetchStrategy) { + + this.fetchSource = fetchSource; + this.fetchedAttribute = fetchedAttribute; + this.fetchStrategy = fetchStrategy; + this.propertyPath = fetchSource.getPropertyPath().append( fetchedAttribute.getName() ); + } + + @Override + public FetchSource getSource() { + return fetchSource; + } + + @Override + public AnyType getFetchedType() { + return (AnyType) fetchedAttribute.getType(); + } + + @Override + public boolean isNullable() { + return fetchedAttribute.isNullable(); + } + + @Override + public String[] toSqlSelectFragments(String alias) { + return new String[0]; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getAdditionalJoinConditions() { + // only pertinent for HQL... + return null; + } + + @Override + public FetchStrategy getFetchStrategy() { + return fetchStrategy; + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public String getQuerySpaceUid() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Fetch[] getFetches() { + return NO_FETCHES; + } + + @Override + public BidirectionalEntityReference[] getBidirectionalEntityReferences() { + return NO_BIDIRECTIONAL_ENTITY_REFERENCES; + } + + @Override + public EntityReference resolveEntityReference() { + return fetchSource.resolveEntityReference(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/AbstractLoadPlanBuildingAssociationVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/AbstractLoadPlanBuildingAssociationVisitationStrategy.java index f4aaeffd79..d99b99d069 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/AbstractLoadPlanBuildingAssociationVisitationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/AbstractLoadPlanBuildingAssociationVisitationStrategy.java @@ -837,6 +837,12 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy // 1) fetch type is SELECT, timing might be IMMEDIATE or DELAYED depending on whether it was defined as lazy // 2) (because the fetch cannot be a JOIN...) do not push it to the stack final FetchStrategy fetchStrategy = determineFetchStrategy( attributeDefinition ); + if ( fetchStrategy.getTiming() != FetchTiming.IMMEDIATE ) { + return false; + } + + final ExpandingFetchSource currentSource = currentSource(); + currentSource.validateFetchPlan( fetchStrategy, attributeDefinition ); // final FetchOwner fetchSource = currentFetchOwner(); // fetchOwner.validateFetchPlan( fetchStrategy, attributeDefinition ); @@ -869,16 +875,24 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy final AssociationAttributeDefinition.AssociationNature nature = attributeDefinition.getAssociationNature(); if ( nature == AssociationAttributeDefinition.AssociationNature.ANY ) { + currentSource.buildAnyFetch( + attributeDefinition, + fetchStrategy + ); return false; } - - if ( nature == AssociationAttributeDefinition.AssociationNature.ENTITY ) { + else if ( nature == AssociationAttributeDefinition.AssociationNature.ENTITY ) { EntityFetch fetch = currentSource.buildEntityFetch( attributeDefinition, fetchStrategy ); if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) { pushToStack( (ExpandingFetchSource) fetch ); + pushedAttributes.add( attributeDefinition ); + return true; + } + else { + return false; } } else { @@ -886,12 +900,13 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy CollectionFetch fetch = currentSource.buildCollectionFetch( attributeDefinition, fetchStrategy ); if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) { pushToCollectionStack( fetch ); + pushedAttributes.add( attributeDefinition ); + return true; + } + else { + return false; } } - if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) { - pushedAttributes.add( attributeDefinition ); - } - return fetchStrategy.getStyle() == FetchStyle.JOIN; } protected abstract FetchStrategy determineFetchStrategy(AssociationAttributeDefinition attributeDefinition); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/ExpandingFetchSource.java b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/ExpandingFetchSource.java index 505f7dd99d..d2636084cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/ExpandingFetchSource.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/ExpandingFetchSource.java @@ -24,6 +24,7 @@ package org.hibernate.loader.plan2.build.spi; import org.hibernate.engine.FetchStrategy; +import org.hibernate.loader.plan2.spi.AnyFetch; import org.hibernate.loader.plan2.spi.BidirectionalEntityReference; import org.hibernate.loader.plan2.spi.CollectionFetch; import org.hibernate.loader.plan2.spi.CompositeFetch; @@ -65,4 +66,8 @@ public interface ExpandingFetchSource extends FetchSource { AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy); + public AnyFetch buildAnyFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy); + } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan2/spi/AnyFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan2/spi/AnyFetch.java new file mode 100644 index 0000000000..886e03cca5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan2/spi/AnyFetch.java @@ -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 AnyFetch extends Fetch, FetchSource { +}