HHH-7841 - Redesign Loader

This commit is contained in:
Steve Ebersole 2013-04-12 14:08:35 -05:00
parent 1d9f6201a0
commit 8bca70e6a9
57 changed files with 1173 additions and 129 deletions

View File

@ -37,8 +37,8 @@ import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.LoadQueryBuilder;
import org.hibernate.persister.entity.OuterJoinLoadable;

View File

@ -57,8 +57,8 @@ import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityReference;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.spi.AfterLoadAction;
import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.ResultSetProcessingContext;

View File

@ -41,10 +41,11 @@ import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.AfterLoadAction;
import org.hibernate.loader.spi.LoadPlanAdvisor;
import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.ScrollableResultSetProcessor;
import org.hibernate.loader.spi.ResultSetProcessor;
@ -58,12 +59,12 @@ import org.hibernate.transform.ResultTransformer;
public class ResultSetProcessorImpl implements ResultSetProcessor {
private static final Logger LOG = Logger.getLogger( ResultSetProcessorImpl.class );
private final LoadPlan loadPlan;
private final LoadPlan baseLoadPlan;
private final boolean hadSubselectFetches;
public ResultSetProcessorImpl(LoadPlan loadPlan) {
this.loadPlan = loadPlan;
this.baseLoadPlan = loadPlan;
LocalVisitationStrategy strategy = new LocalVisitationStrategy();
LoadPlanVisitor.visit( loadPlan, strategy );
@ -78,6 +79,7 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
@Override
public List extractResults(
LoadPlanAdvisor loadPlanAdvisor,
ResultSet resultSet,
final SessionImplementor session,
QueryParameters queryParameters,
@ -87,7 +89,9 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
ResultTransformer forcedResultTransformer,
List<AfterLoadAction> afterLoadActionList) throws SQLException {
handlePotentiallyEmptyCollectionRootReturns( queryParameters.getCollectionKeys(), resultSet, session );
final LoadPlan loadPlan = loadPlanAdvisor.advise( this.baseLoadPlan );
handlePotentiallyEmptyCollectionRootReturns( loadPlan, queryParameters.getCollectionKeys(), resultSet, session );
final int maxRows;
final RowSelection selection = queryParameters.getRowSelection();
@ -163,6 +167,7 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
private void handlePotentiallyEmptyCollectionRootReturns(
LoadPlan loadPlan,
Serializable[] collectionKeys,
ResultSet resultSet,
SessionImplementor session) {

View File

@ -32,7 +32,7 @@ import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.LoadPlanBuildingContext;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;

View File

@ -34,11 +34,11 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.spi.AbstractLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.build.AbstractLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.build.LoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;

View File

@ -43,8 +43,8 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
private final CollectionAliases collectionAliases;
private final EntityAliases elementEntityAliases;
private final FetchOwner indexGraph;
private final FetchOwner elementGraph;
private final FetchableCollectionIndex indexGraph;
private final FetchableCollectionElement elementGraph;
protected AbstractCollectionReference(
SessionFactoryImplementor sessionFactory,
@ -67,7 +67,7 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
this.elementGraph = buildElementGraph( getCollectionPersister() );
}
private FetchOwner buildIndexGraph(CollectionPersister persister) {
private FetchableCollectionIndex buildIndexGraph(CollectionPersister persister) {
if ( persister.hasIndex() ) {
final Type type = persister.getIndexType();
if ( type.isAssociationType() ) {
@ -83,7 +83,7 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
return null;
}
private FetchOwner buildElementGraph(CollectionPersister persister) {
private FetchableCollectionElement buildElementGraph(CollectionPersister persister) {
final Type type = persister.getElementType();
if ( type.isAssociationType() ) {
if ( type.isEntityType() ) {
@ -97,6 +97,20 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
return null;
}
protected AbstractCollectionReference(AbstractCollectionReference original, CopyContext copyContext) {
super( original );
this.alias = original.alias;
this.lockMode = original.lockMode;
this.collectionPersister = original.collectionPersister;
this.propertyPath = original.propertyPath;
this.collectionAliases = original.collectionAliases;
this.elementEntityAliases = original.elementEntityAliases;
this.indexGraph = original.indexGraph == null ? null : original.indexGraph.makeCopy( copyContext );
this.elementGraph = original.elementGraph == null ? null : original.elementGraph.makeCopy( copyContext );
}
@Override
public PropertyPath getPropertyPath() {
return propertyPath;

View File

@ -24,14 +24,12 @@
package org.hibernate.loader.plan.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.spi.ResultSetProcessingContext;
/**
* @author Steve Ebersole
@ -45,10 +43,39 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) {
super( factory );
this.alias = alias;
this.lockMode = lockMode;
validate();
}
private void validate() {
if ( alias == null ) {
throw new HibernateException( "alias must be specified" );
}
this.lockMode = lockMode;
}
/**
* A "copy" constructor. Used while making clones/copies of this.
*
* @param original
*/
protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) {
super( original );
this.alias = original.alias;
this.lockMode = original.lockMode;
validate();
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList();
}
else {
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
}
this.fetches = fetchesCopy;
}
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
}
public String getAlias() {

View File

@ -37,6 +37,10 @@ public abstract class AbstractPlanNode {
this.sessionFactory = sessionFactory;
}
public AbstractPlanNode(AbstractPlanNode original) {
this( original.sessionFactory() );
}
protected SessionFactoryImplementor sessionFactory() {
return sessionFactory;
}

View File

@ -57,6 +57,17 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
this.propertyPath = owner.getPropertyPath().append( ownerProperty );
}
public AbstractSingularAttributeFetch(
AbstractSingularAttributeFetch original,
CopyContext copyContext,
FetchOwner fetchOwnerCopy) {
super( original, copyContext );
this.owner = fetchOwnerCopy;
this.ownerProperty = original.ownerProperty;
this.fetchStrategy = original.fetchStrategy;
this.propertyPath = original.propertyPath;
}
@Override
public FetchOwner getOwner() {
return owner;

View File

@ -66,6 +66,12 @@ public class CollectionFetch extends AbstractCollectionReference implements Fetc
fetchOwner.addFetch( this );
}
protected CollectionFetch(CollectionFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext );
this.fetchOwner = fetchOwnerCopy;
this.fetchStrategy = original.fetchStrategy;
}
@Override
public FetchOwner getOwner() {
return fetchOwner;
@ -90,4 +96,12 @@ public class CollectionFetch extends AbstractCollectionReference implements Fetc
public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public CollectionFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) {
copyContext.getReturnGraphVisitationStrategy().startingCollectionFetch( this );
final CollectionFetch copy = new CollectionFetch( this, copyContext, fetchOwnerCopy );
copyContext.getReturnGraphVisitationStrategy().finishingCollectionFetch( this );
return copy;
}
}

View File

@ -36,7 +36,7 @@ import org.hibernate.loader.spi.ResultSetProcessingContext;
/**
* @author Steve Ebersole
*/
public class CollectionReturn extends AbstractCollectionReference implements Return {
public class CollectionReturn extends AbstractCollectionReference implements Return, CopyableReturn {
private final String ownerEntityName;
private final String ownerProperty;
@ -61,6 +61,12 @@ public class CollectionReturn extends AbstractCollectionReference implements Ret
this.ownerProperty = ownerProperty;
}
public CollectionReturn(CollectionReturn original, CopyContext copyContext) {
super( original, copyContext );
this.ownerEntityName = original.ownerEntityName;
this.ownerProperty = original.ownerProperty;
}
/**
* Returns the class owning the collection.
*
@ -98,4 +104,9 @@ public class CollectionReturn extends AbstractCollectionReference implements Ret
public String toString() {
return "CollectionReturn(" + getCollectionPersister().getRole() + ")";
}
@Override
public CollectionReturn makeCopy(CopyContext copyContext) {
return new CollectionReturn( this, copyContext );
}
}

View File

@ -1,6 +1,7 @@
package org.hibernate.loader.plan.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.HibernateException;
@ -8,6 +9,7 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -16,12 +18,13 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
/**
* @author Steve Ebersole
*/
public class CompositeElementGraph extends AbstractPlanNode implements FetchOwner {
public class CompositeElementGraph extends AbstractPlanNode implements FetchableCollectionElement {
private final CollectionReference collectionReference;
private final PropertyPath propertyPath;
private final CollectionPersister collectionPersister;
private List<Fetch> fetches;
public CompositeElementGraph(
SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference,
@ -33,6 +36,26 @@ public class CompositeElementGraph extends AbstractPlanNode implements FetchOwne
this.propertyPath = collectionPath.append( "<elements>" );
}
public CompositeElementGraph(CompositeElementGraph original, CopyContext copyContext) {
super( original );
this.collectionReference = original.collectionReference;
this.collectionPersister = original.collectionPersister;
this.propertyPath = original.propertyPath;
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList();
}
else {
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
}
this.fetches = fetchesCopy;
}
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
}
@Override
public void addFetch(Fetch fetch) {
if ( fetches == null ) {
@ -89,4 +112,9 @@ public class CompositeElementGraph extends AbstractPlanNode implements FetchOwne
LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
}
@Override
public CompositeElementGraph makeCopy(CopyContext copyContext) {
return new CompositeElementGraph( this, copyContext );
}
}

View File

@ -31,6 +31,7 @@ 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.spi.build.LoadPlanBuildingContext;
import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -50,6 +51,10 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN );
}
public CompositeFetch(CompositeFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext, fetchOwnerCopy );
}
@Override
public EntityPersister retrieveFetchSourcePersister() {
return getOwner().retrieveFetchSourcePersister();
@ -86,4 +91,12 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public CompositeFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) {
copyContext.getReturnGraphVisitationStrategy().startingCompositeFetch( this );
final CompositeFetch copy = new CompositeFetch( this, copyContext, fetchOwnerCopy );
copyContext.getReturnGraphVisitationStrategy().finishingCompositeFetch( this );
return copy;
}
}

View File

@ -1,6 +1,7 @@
package org.hibernate.loader.plan.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.HibernateException;
@ -8,6 +9,7 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -16,7 +18,7 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
/**
* @author Steve Ebersole
*/
public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner {
public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex {
private final CollectionReference collectionReference;
private final PropertyPath propertyPath;
private final CollectionPersister collectionPersister;
@ -33,6 +35,26 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner
this.propertyPath = propertyPath.append( "<index>" );
}
protected CompositeIndexGraph(CompositeIndexGraph original, CopyContext copyContext) {
super( original );
this.collectionReference = original.collectionReference;
this.collectionPersister = original.collectionPersister;
this.propertyPath = original.propertyPath;
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList();
}
else {
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
}
this.fetches = fetchesCopy;
}
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
}
@Override
public void addFetch(Fetch fetch) {
if ( fetches == null ) {
@ -89,4 +111,9 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner
LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
}
@Override
public CompositeIndexGraph makeCopy(CopyContext copyContext) {
return new CompositeIndexGraph( this, copyContext );
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.plan.spi;
import org.hibernate.loader.plan.spi.visit.ReturnGraphVisitationStrategy;
/**
* @author Steve Ebersole
*/
public interface CopyContext {
public ReturnGraphVisitationStrategy getReturnGraphVisitationStrategy();
}

View File

@ -0,0 +1,31 @@
/*
* 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.plan.spi;
/**
* @author Steve Ebersole
*/
public interface CopyableFetch {
public Fetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy);
}

View File

@ -0,0 +1,38 @@
/*
* 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.plan.spi;
/**
* @author Steve Ebersole
*/
public interface CopyableReturn {
/**
* Makes a deep copy.
*
* @return
*/
public CopyableReturn makeCopy(CopyContext copyContext);
}

View File

@ -1,6 +1,7 @@
package org.hibernate.loader.plan.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.LockMode;
@ -9,6 +10,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -18,7 +20,7 @@ import org.hibernate.type.AssociationType;
/**
* @author Steve Ebersole
*/
public class EntityElementGraph extends AbstractPlanNode implements FetchOwner, EntityReference {
public class EntityElementGraph extends AbstractPlanNode implements FetchableCollectionElement, EntityReference {
private final CollectionReference collectionReference;
private final CollectionPersister collectionPersister;
private final AssociationType elementType;
@ -42,6 +44,29 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchOwner,
this.propertyPath = collectionPath.append( "<elements>" );
}
public EntityElementGraph(EntityElementGraph original, CopyContext copyContext) {
super( original );
this.collectionReference = original.collectionReference;
this.collectionPersister = original.collectionReference.getCollectionPersister();
this.elementType = original.elementType;
this.elementPersister = original.elementPersister;
this.propertyPath = original.propertyPath;
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList();
}
else {
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
}
this.fetches = fetchesCopy;
}
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
}
@Override
public String getAlias() {
return null;
@ -139,6 +164,11 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchOwner,
this.identifierDescription = identifierDescription;
}
@Override
public EntityElementGraph makeCopy(CopyContext copyContext) {
return new EntityElementGraph( this, copyContext );
}
@Override
public String toString() {
return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")";

View File

@ -34,11 +34,11 @@ import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases;
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.AssociationType;
import org.hibernate.type.EntityType;
/**
@ -70,6 +70,20 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() );
}
/**
* Copy constructor.
*
* @param original The original fetch
* @param copyContext Access to contextual needs for the copy operation
*/
protected EntityFetch(EntityFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext, fetchOwnerCopy );
this.sqlTableAlias = original.sqlTableAlias;
this.entityAliases = original.entityAliases;
this.associationType = original.associationType;
this.persister = original.persister;
}
public EntityType getAssociationType() {
return associationType;
}
@ -262,4 +276,12 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
public String toString() {
return "EntityFetch(" + getPropertyPath().getFullPath() + " -> " + persister.getEntityName() + ")";
}
@Override
public EntityFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) {
copyContext.getReturnGraphVisitationStrategy().startingEntityFetch( this );
final EntityFetch copy = new EntityFetch( this, copyContext, fetchOwnerCopy );
copyContext.getReturnGraphVisitationStrategy().finishingEntityFetch( this );
return copy;
}
}

View File

@ -24,6 +24,7 @@
package org.hibernate.loader.plan.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.LockMode;
@ -32,6 +33,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -41,7 +43,7 @@ import org.hibernate.type.AssociationType;
/**
* @author Steve Ebersole
*/
public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, EntityReference {
public class EntityIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex, EntityReference {
private final CollectionReference collectionReference;
private final CollectionPersister collectionPersister;
private final AssociationType indexType;
@ -64,6 +66,28 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, En
this.propertyPath = collectionPath.append( "<index>" ); // todo : do we want the <index> part?
}
public EntityIndexGraph(EntityIndexGraph original, CopyContext copyContext) {
super( original );
this.collectionReference = original.collectionReference;
this.collectionPersister = original.collectionReference.getCollectionPersister();
this.indexType = original.indexType;
this.indexPersister = original.indexPersister;
this.propertyPath = original.propertyPath;
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
if ( fetches == null || fetches.size() == 0 ) {
this.fetches = Collections.emptyList();
}
else {
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
for ( Fetch fetch : fetches ) {
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
}
this.fetches = fetchesCopy;
}
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
}
@Override
public String getAlias() {
return null;
@ -160,4 +184,9 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, En
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
this.identifierDescription = identifierDescription;
}
@Override
public EntityIndexGraph makeCopy(CopyContext copyContext) {
return new EntityIndexGraph( this, copyContext );
}
}

View File

@ -23,9 +23,7 @@
*/
package org.hibernate.loader.plan.spi;
import org.hibernate.AssertionFailure;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister;
@ -35,7 +33,8 @@ import org.hibernate.persister.entity.EntityPersister;
*
* @author Steve Ebersole
*/
public interface EntityReference extends IdentifierDescriptionInjectable, ResultSetProcessingContext.EntityKeyResolutionContext {
public interface EntityReference
extends IdentifierDescriptionInjectable, ResultSetProcessingContext.EntityKeyResolutionContext {
/**
* Retrieve the alias associated with the persister (entity/collection).
*

View File

@ -34,6 +34,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath;
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;
@ -44,7 +45,7 @@ import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierReso
/**
* @author Steve Ebersole
*/
public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference {
public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference, CopyableReturn {
private final EntityAliases entityAliases;
private final String sqlTableAlias;
@ -69,6 +70,13 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
this.persister = sessionFactory.getEntityPersister( entityName );
}
protected EntityReturn(EntityReturn original, CopyContext copyContext) {
super( original, copyContext );
this.entityAliases = original.entityAliases;
this.sqlTableAlias = original.sqlTableAlias;
this.persister = original.persister;
}
@Override
public String getAlias() {
return super.getAlias();
@ -205,4 +213,9 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
public String toString() {
return "EntityReturn(" + persister.getEntityName() + ")";
}
@Override
public EntityReturn makeCopy(CopyContext copyContext) {
return new EntityReturn( this, copyContext );
}
}

View File

@ -37,7 +37,7 @@ import org.hibernate.loader.spi.ResultSetProcessingContext;
*
* @author Steve Ebersole
*/
public interface Fetch {
public interface Fetch extends CopyableFetch {
/**
* Obtain the owner of this fetch.
*
@ -64,4 +64,7 @@ public interface Fetch {
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException;
public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException;
@Override
public Fetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy);
}

View File

@ -25,6 +25,7 @@ package org.hibernate.loader.plan.spi;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
@ -91,4 +92,5 @@ public interface FetchOwner {
CompositionDefinition attributeDefinition,
LoadPlanBuildingContext loadPlanBuildingContext);
}

View File

@ -0,0 +1,32 @@
/*
* 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.plan.spi;
/**
* @author Steve Ebersole
*/
public interface FetchableCollectionElement extends FetchOwner, CopyableReturn {
@Override
public FetchableCollectionElement makeCopy(CopyContext copyContext);
}

View File

@ -0,0 +1,34 @@
/*
* 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.plan.spi;
/**
* A collection index which can be a fetch owner.
*
* @author Steve Ebersole
*/
public interface FetchableCollectionIndex extends FetchOwner, CopyableReturn {
@Override
public FetchableCollectionIndex makeCopy(CopyContext copyContext);
}

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.build;
import java.io.Serializable;
import java.sql.ResultSet;
@ -48,6 +48,17 @@ import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.GeneratedCollectionAliases;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReference;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReference;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.Fetch;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.IdentifierDescription;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;

View File

@ -21,14 +21,15 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.build;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
/**
* Coordinates building of a {@link LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and
* Coordinates building of a {@link org.hibernate.loader.plan.spi.LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and
* {@link LoadPlanBuilderStrategy}
*
* @author Steve Ebersole

View File

@ -21,12 +21,13 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.build;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.persister.walking.spi.AssociationVisitationStrategy;
/**
* Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link LoadPlan} instances.
* Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link org.hibernate.loader.plan.spi.LoadPlan} instances.
*
* @author Steve Ebersole
*/

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.build;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.CollectionAliases;

View File

@ -0,0 +1,118 @@
/*
* 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.plan.spi.visit;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.plan.spi.ScalarReturn;
/**
* @author Steve Ebersole
*/
public class DelegatedLoadPlanVisitationStrategy implements LoadPlanVisitationStrategy {
private final ReturnGraphVisitationStrategy returnGraphVisitationStrategy;
public DelegatedLoadPlanVisitationStrategy(ReturnGraphVisitationStrategy returnGraphVisitationStrategy) {
this.returnGraphVisitationStrategy = returnGraphVisitationStrategy;
}
@Override
public void start(LoadPlan loadPlan) {
}
@Override
public void finish(LoadPlan loadPlan) {
}
@Override
public void startingRootReturn(Return rootReturn) {
returnGraphVisitationStrategy.startingRootReturn( rootReturn );
}
@Override
public void finishingRootReturn(Return rootReturn) {
returnGraphVisitationStrategy.finishingRootReturn( rootReturn );
}
@Override
public void handleScalarReturn(ScalarReturn scalarReturn) {
returnGraphVisitationStrategy.handleScalarReturn( scalarReturn );
}
@Override
public void handleEntityReturn(EntityReturn rootEntityReturn) {
returnGraphVisitationStrategy.handleEntityReturn( rootEntityReturn );
}
@Override
public void handleCollectionReturn(CollectionReturn rootCollectionReturn) {
returnGraphVisitationStrategy.handleCollectionReturn( rootCollectionReturn );
}
@Override
public void startingFetches(FetchOwner fetchOwner) {
returnGraphVisitationStrategy.startingFetches( fetchOwner );
}
@Override
public void finishingFetches(FetchOwner fetchOwner) {
returnGraphVisitationStrategy.finishingFetches( fetchOwner );
}
@Override
public void startingEntityFetch(EntityFetch fetch) {
returnGraphVisitationStrategy.startingEntityFetch( fetch );
}
@Override
public void finishingEntityFetch(EntityFetch fetch) {
returnGraphVisitationStrategy.finishingEntityFetch( fetch );
}
@Override
public void startingCollectionFetch(CollectionFetch fetch) {
returnGraphVisitationStrategy.startingCollectionFetch( fetch );
}
@Override
public void finishingCollectionFetch(CollectionFetch fetch) {
returnGraphVisitationStrategy.finishingCollectionFetch( fetch );
}
@Override
public void startingCompositeFetch(CompositeFetch fetch) {
returnGraphVisitationStrategy.startingCompositeFetch( fetch );
}
@Override
public void finishingCompositeFetch(CompositeFetch fetch) {
returnGraphVisitationStrategy.finishingCompositeFetch( fetch );
}
}

View File

@ -0,0 +1,41 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.plan.spi.visit;
import org.hibernate.loader.plan.spi.LoadPlan;
/**
* @author Steve Ebersole
*/
public interface LoadPlanVisitationStrategy extends ReturnGraphVisitationStrategy {
/**
* Notification we are preparing to start visitation.
*/
public void start(LoadPlan loadPlan);
/**
* Notification we are finished visitation.
*/
public void finish(LoadPlan loadPlan);
}

View File

@ -21,84 +21,81 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.visit;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.plan.spi.ScalarReturn;
/**
* @author Steve Ebersole
*/
public class LoadPlanVisitationStrategyAdapter implements LoadPlanVisitationStrategy {
public static final LoadPlanVisitationStrategyAdapter INSTANCE = new LoadPlanVisitationStrategyAdapter();
@Override
public void start(LoadPlan loadPlan) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finish(LoadPlan loadPlan) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startingRootReturn(Return rootReturn) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finishingRootReturn(Return rootReturn) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void handleScalarReturn(ScalarReturn scalarReturn) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void handleEntityReturn(EntityReturn rootEntityReturn) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void handleCollectionReturn(CollectionReturn rootCollectionReturn) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startingFetches(FetchOwner fetchOwner) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finishingFetches(FetchOwner fetchOwner) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startingEntityFetch(EntityFetch entityFetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finishingEntityFetch(EntityFetch entityFetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startingCollectionFetch(CollectionFetch collectionFetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finishingCollectionFetch(CollectionFetch collectionFetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startingCompositeFetch(CompositeFetch fetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void finishingCompositeFetch(CompositeFetch fetch) {
//To change body of implemented methods use File | Settings | File Templates.
}
}

View File

@ -0,0 +1,53 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.plan.spi.visit;
import org.hibernate.loader.plan.spi.LoadPlan;
/**
* Visitor for processing {@link org.hibernate.loader.plan.spi.Return} graphs
*
* @author Steve Ebersole
*/
public class LoadPlanVisitor {
public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) {
new LoadPlanVisitor( strategy ).visit( loadPlan );
}
private final LoadPlanVisitationStrategy strategy;
private final ReturnGraphVisitor returnGraphVisitor;
public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) {
this.strategy = strategy;
this.returnGraphVisitor = new ReturnGraphVisitor( strategy );
}
private void visit(LoadPlan loadPlan) {
strategy.start( loadPlan );
returnGraphVisitor.visit( loadPlan.getReturns() );
strategy.finish( loadPlan );
}
}

View File

@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* 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.
@ -21,25 +21,26 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.visit;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.plan.spi.ScalarReturn;
/**
* A strategy for visiting a root {@link Return} and fetches it defines.
*
* @author Steve Ebersole
*/
public interface LoadPlanVisitationStrategy {
public interface ReturnGraphVisitationStrategy {
/**
* Notification we are preparing to start visitation.
*/
public void start(LoadPlan loadPlan);
/**
* Notification we are finished visitation.
*/
public void finish(LoadPlan loadPlan);
/**
* Notification that a new root return branch is being started. Will be followed by calls to one of the following
* based on the type of return:<ul>
* Notification that a new root return branch is being started. Will be followed by calls
* to one of the following based on the type of return:<ul>
* <li>{@link #handleScalarReturn}</li>
* <li>{@link #handleEntityReturn}</li>
* <li>{@link #handleCollectionReturn}</li>
@ -57,8 +58,8 @@ public interface LoadPlanVisitationStrategy {
public void finishingRootReturn(Return rootReturn);
/**
* Notification that a scalar return is being processed. Will be surrounded by calls to {@link #startingRootReturn}
* and {@link #finishingRootReturn}
* Notification that a scalar return is being processed. Will be surrounded by calls to
* {@link #startingRootReturn} and {@link #finishingRootReturn}
*
* @param scalarReturn The scalar return
*/

View File

@ -0,0 +1,92 @@
/*
* 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.plan.spi.visit;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.plan.spi.ScalarReturn;
/**
* @author Steve Ebersole
*/
public class ReturnGraphVisitationStrategyAdapter implements ReturnGraphVisitationStrategy {
public static final ReturnGraphVisitationStrategyAdapter INSTANCE = new ReturnGraphVisitationStrategyAdapter();
@Override
public void startingRootReturn(Return rootReturn) {
}
@Override
public void finishingRootReturn(Return rootReturn) {
}
@Override
public void handleScalarReturn(ScalarReturn scalarReturn) {
}
@Override
public void handleEntityReturn(EntityReturn rootEntityReturn) {
}
@Override
public void handleCollectionReturn(CollectionReturn rootCollectionReturn) {
}
@Override
public void startingFetches(FetchOwner fetchOwner) {
}
@Override
public void finishingFetches(FetchOwner fetchOwner) {
}
@Override
public void startingEntityFetch(EntityFetch entityFetch) {
}
@Override
public void finishingEntityFetch(EntityFetch entityFetch) {
}
@Override
public void startingCollectionFetch(CollectionFetch collectionFetch) {
}
@Override
public void finishingCollectionFetch(CollectionFetch collectionFetch) {
}
@Override
public void startingCompositeFetch(CompositeFetch fetch) {
}
@Override
public void finishingCompositeFetch(CompositeFetch fetch) {
}
}

View File

@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* 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.
@ -21,32 +21,40 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan.spi;
package org.hibernate.loader.plan.spi.visit;
import java.util.List;
import org.hibernate.loader.plan.spi.CollectionFetch;
import org.hibernate.loader.plan.spi.CollectionReturn;
import org.hibernate.loader.plan.spi.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.Fetch;
import org.hibernate.loader.plan.spi.FetchOwner;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.plan.spi.ScalarReturn;
/**
* Visitor for processing {@link Return} graphs
*
* @author Steve Ebersole
*/
public class LoadPlanVisitor {
public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) {
new LoadPlanVisitor( strategy ).visit( loadPlan );
}
public class ReturnGraphVisitor {
private final ReturnGraphVisitationStrategy strategy;
private final LoadPlanVisitationStrategy strategy;
public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) {
public ReturnGraphVisitor(ReturnGraphVisitationStrategy strategy) {
this.strategy = strategy;
}
private void visit(LoadPlan loadPlan) {
strategy.start( loadPlan );
for ( Return rootReturn : loadPlan.getReturns() ) {
public void visit(Return... rootReturns) {
for ( Return rootReturn : rootReturns ) {
visitRootReturn( rootReturn );
}
}
strategy.finish( loadPlan );
public void visit(List<Return> rootReturns) {
for ( Return rootReturn : rootReturns ) {
visitRootReturn( rootReturn );
}
}
private void visitRootReturn(Return rootReturn) {
@ -117,5 +125,4 @@ public class LoadPlanVisitor {
);
}
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.spi;
import org.hibernate.loader.plan.spi.LoadPlan;
/**
* @author Steve Ebersole
*/
public interface LoadPlanAdvisor {
public LoadPlan advise(LoadPlan loadPlan);
}

View File

@ -0,0 +1,38 @@
/*
* 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.spi;
import org.hibernate.loader.plan.spi.LoadPlan;
/**
* @author Steve Ebersole
*/
public class NoOpLoadPlanAdvisor implements LoadPlanAdvisor {
public static final NoOpLoadPlanAdvisor INSTANCE = new NoOpLoadPlanAdvisor();
@Override
public LoadPlan advise(LoadPlan loadPlan) {
return loadPlan;
}
}

View File

@ -48,17 +48,20 @@ public interface ResultSetProcessor {
*
* Semi-copy of {@link org.hibernate.loader.Loader#doQuery}, with focus on just the ResultSet processing bit.
*
* @param loadPlanAdvisor A dynamic advisor on the load plan.
* @param resultSet The result set being processed.
* @param session The originating session
* @param queryParameters The "parameters" used to build the query
* @param returnProxies Can proxies be returned (not the same as can they be created!)
* @param forcedResultTransformer My old "friend" ResultTransformer...
* @param afterLoadActions Actions to be performed after loading an entity.
*
* @return The extracted results list.
*
* @throws java.sql.SQLException Indicates a problem access the JDBC ResultSet
*/
public List extractResults(
LoadPlanAdvisor loadPlanAdvisor,
ResultSet resultSet,
SessionImplementor session,
QueryParameters queryParameters,

View File

@ -96,9 +96,6 @@ import org.hibernate.loader.entity.BatchingEntityLoaderBuilder;
import org.hibernate.loader.entity.CascadeEntityLoader;
import org.hibernate.loader.entity.EntityLoader;
import org.hibernate.loader.entity.UniqueEntityLoader;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanBuilder;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
@ -130,10 +127,6 @@ import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
import org.hibernate.sql.Update;
import org.hibernate.sql.ordering.antlr.ColumnMapper;
import org.hibernate.sql.ordering.antlr.ColumnReference;
import org.hibernate.sql.ordering.antlr.FormulaReference;
import org.hibernate.sql.ordering.antlr.SqlValueReference;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.AssociationType;

View File

@ -48,8 +48,9 @@ import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl;
import org.hibernate.loader.internal.ResultSetProcessorImpl;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanBuilder;
import org.hibernate.loader.plan.spi.build.LoadPlanBuilder;
import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.ExtraAssertions;
@ -114,6 +115,7 @@ public class EntityAssociationResultSetProcessorTest extends BaseCoreFunctionalT
ResultSet resultSet = ps.executeQuery();
results.addAll(
resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet,
(SessionImplementor) workSession,
new QueryParameters(),
@ -207,6 +209,7 @@ public class EntityAssociationResultSetProcessorTest extends BaseCoreFunctionalT
ResultSet resultSet = ps.executeQuery();
results.addAll(
resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet,
(SessionImplementor) workSession,
new QueryParameters(),

View File

@ -31,14 +31,10 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.junit.Test;
@ -47,14 +43,14 @@ import org.hibernate.Session;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.collections.IdentitySet;
import org.hibernate.jdbc.Work;
import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl;
import org.hibernate.loader.internal.ResultSetProcessorImpl;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanBuilder;
import org.hibernate.loader.plan.spi.build.LoadPlanBuilder;
import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.ExtraAssertions;
@ -120,6 +116,7 @@ public class EntityWithCollectionResultSetProcessorTest extends BaseCoreFunction
ResultSet resultSet = ps.executeQuery();
results.addAll(
resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet,
(SessionImplementor) workSession,
new QueryParameters(),

View File

@ -42,8 +42,9 @@ import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl;
import org.hibernate.loader.internal.ResultSetProcessorImpl;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanBuilder;
import org.hibernate.loader.plan.spi.build.LoadPlanBuilder;
import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
import org.hibernate.persister.entity.EntityPersister;
import org.junit.Test;
@ -104,6 +105,7 @@ public class SimpleResultSetProcessorTest extends BaseCoreFunctionalTestCase {
ResultSet resultSet = ps.executeQuery();
results.addAll(
resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet,
(SessionImplementor) workSession,
new QueryParameters(),

View File

@ -36,6 +36,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl;
import org.hibernate.loader.plan.internal.CascadeLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.build.LoadPlanBuilder;
import org.hibernate.loader.spi.LoadQueryBuilder;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;

View File

@ -27,6 +27,7 @@ import javax.persistence.EntityManagerFactory;
import java.io.Serializable;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.internal.metamodel.EntityTypeImpl;
/**
* Contract giving access to the underlying {@link org.hibernate.SessionFactory} from an {@link javax.persistence.EntityManagerFactory}
@ -40,4 +41,6 @@ public interface HibernateEntityManagerFactory extends EntityManagerFactory, Ser
* @return The underlying Hibernate SessionFactory
*/
public SessionFactory getSessionFactory();
public EntityTypeImpl getEntityTypeByName(String entityName);
}

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.jpa.internal.graph;
package org.hibernate.jpa.graph.internal;
import javax.persistence.AttributeNode;
import javax.persistence.Subgraph;
@ -36,24 +36,27 @@ import org.jboss.logging.Logger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.jpa.graph.spi.GraphNodeImplementor;
/**
* Base class for EntityGraph and Subgraph implementations.
*
* @author Steve Ebersole
*/
public abstract class GraphNode<T> {
private static final Logger log = Logger.getLogger( GraphNode.class );
public abstract class AbstractGraphNode<T> implements GraphNodeImplementor {
private static final Logger log = Logger.getLogger( AbstractGraphNode.class );
private final HibernateEntityManagerFactory entityManagerFactory;
private final boolean mutable;
private Map<String, AttributeNode<?>> attributeNodeMap;
protected GraphNode(HibernateEntityManagerFactory entityManagerFactory, boolean mutable) {
protected AbstractGraphNode(HibernateEntityManagerFactory entityManagerFactory, boolean mutable) {
this.entityManagerFactory = entityManagerFactory;
this.mutable = mutable;
}
protected GraphNode(GraphNode<T> original, boolean mutable) {
protected AbstractGraphNode(AbstractGraphNode<T> original, boolean mutable) {
this.entityManagerFactory = original.entityManagerFactory;
this.mutable = mutable;
this.attributeNodeMap = makeSafeMapCopy( original.attributeNodeMap );
@ -75,11 +78,13 @@ public abstract class GraphNode<T> {
return copy;
}
protected HibernateEntityManagerFactory entityManagerFactory() {
@Override
public HibernateEntityManagerFactory entityManagerFactory() {
return entityManagerFactory;
}
protected List<AttributeNode<?>> attributeNodes() {
@Override
public List<AttributeNode<?>> attributeNodes() {
if ( attributeNodeMap == null ) {
return Collections.emptyList();
}
@ -105,8 +110,8 @@ public abstract class GraphNode<T> {
protected abstract Attribute<T,?> resolveAttribute(String attributeName);
protected AttributeNodeImpl<?> buildAttributeNode(Attribute<T, ?> attribute) {
return new AttributeNodeImpl<Object>( entityManagerFactory, attribute );
protected <X> AttributeNodeImpl<X> buildAttributeNode(Attribute<T, X> attribute) {
return new AttributeNodeImpl<X>( entityManagerFactory, attribute );
}
protected AttributeNodeImpl addAttributeNode(AttributeNodeImpl attributeNode) {

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.jpa.internal.graph;
package org.hibernate.jpa.graph.internal;
import javax.persistence.AttributeNode;
import javax.persistence.Subgraph;
@ -34,6 +34,7 @@ import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
import org.hibernate.jpa.internal.metamodel.Helper;
import org.hibernate.jpa.internal.metamodel.PluralAttributeImpl;
import org.hibernate.persister.collection.QueryableCollection;
@ -47,14 +48,14 @@ import org.hibernate.type.Type;
*
* @author Steve Ebersole
*/
public class AttributeNodeImpl<T> implements AttributeNode<T> {
public class AttributeNodeImpl<T> implements AttributeNode<T>, AttributeNodeImplementor<T> {
private final HibernateEntityManagerFactory entityManagerFactory;
private final Attribute attribute;
private final Attribute<?,T> attribute;
private Map<Class, Subgraph> subgraphMap;
private Map<Class, Subgraph> keySubgraphMap;
public AttributeNodeImpl(HibernateEntityManagerFactory entityManagerFactory, Attribute attribute) {
public <X> AttributeNodeImpl(HibernateEntityManagerFactory entityManagerFactory, Attribute<X,T> attribute) {
this.entityManagerFactory = entityManagerFactory;
this.attribute = attribute;
}
@ -64,7 +65,7 @@ public class AttributeNodeImpl<T> implements AttributeNode<T> {
*/
private AttributeNodeImpl(
HibernateEntityManagerFactory entityManagerFactory,
Attribute attribute,
Attribute<?,T> attribute,
Map<Class, Subgraph> subgraphMap,
Map<Class, Subgraph> keySubgraphMap) {
this.entityManagerFactory = entityManagerFactory;
@ -73,11 +74,17 @@ public class AttributeNodeImpl<T> implements AttributeNode<T> {
this.keySubgraphMap = keySubgraphMap;
}
private SessionFactoryImplementor sessionFactory() {
return (SessionFactoryImplementor) entityManagerFactory.getSessionFactory();
@Override
public HibernateEntityManagerFactory entityManagerFactory() {
return entityManagerFactory;
}
public Attribute getAttribute() {
private SessionFactoryImplementor sessionFactory() {
return (SessionFactoryImplementor) entityManagerFactory().getSessionFactory();
}
@Override
public Attribute<?,T> getAttribute() {
return attribute;
}
@ -102,11 +109,15 @@ public class AttributeNodeImpl<T> implements AttributeNode<T> {
@SuppressWarnings("unchecked")
public <T> Subgraph<T> makeSubgraph() {
return (Subgraph<T>) makeSubgraph( null );
return (Subgraph<T>) internalMakeSubgraph( null );
}
@SuppressWarnings("unchecked")
public <X extends T> Subgraph<X> makeSubgraph(Class<X> type) {
return (Subgraph<X>) internalMakeSubgraph( type );
}
private Subgraph internalMakeSubgraph(Class type) {
if ( attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC
|| attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED ) {
throw new IllegalArgumentException(
@ -239,7 +250,8 @@ public class AttributeNodeImpl<T> implements AttributeNode<T> {
return subgraph;
}
AttributeNodeImpl<T> makeImmutableCopy() {
@Override
public AttributeNodeImpl<T> makeImmutableCopy() {
return new AttributeNodeImpl<T>(
this.entityManagerFactory,
this.attribute,

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.jpa.internal.graph;
package org.hibernate.jpa.graph.internal;
import javax.persistence.AttributeNode;
import javax.persistence.EntityGraph;
@ -39,7 +39,7 @@ import org.hibernate.jpa.HibernateEntityManagerFactory;
*
* @author Steve Ebersole
*/
public class EntityGraphImpl<T> extends GraphNode<T> implements EntityGraph<T> {
public class EntityGraphImpl<T> extends AbstractGraphNode<T> implements EntityGraph<T> {
private final String name;
private final EntityType<T> entityType;
@ -63,6 +63,10 @@ public class EntityGraphImpl<T> extends GraphNode<T> implements EntityGraph<T> {
this.entityType = original.entityType;
}
public EntityType<T> getEntityType() {
return entityType;
}
@Override
public String getName() {
return name;
@ -144,6 +148,11 @@ public class EntityGraphImpl<T> extends GraphNode<T> implements EntityGraph<T> {
return attribute;
}
@SuppressWarnings("unchecked")
public boolean appliesTo(String entityName) {
return appliesTo( entityManagerFactory().getEntityTypeByName( entityName ) );
}
public boolean appliesTo(EntityType<? super T> entityType) {
if ( this.entityType.equals( entityType ) ) {
return true;

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.jpa.internal.graph;
package org.hibernate.jpa.graph.internal;
import javax.persistence.AttributeNode;
import javax.persistence.Subgraph;
@ -34,7 +34,7 @@ import org.hibernate.jpa.HibernateEntityManagerFactory;
/**
* @author Steve Ebersole
*/
public class SubgraphImpl<T> extends GraphNode<T> implements Subgraph<T> {
public class SubgraphImpl<T> extends AbstractGraphNode<T> implements Subgraph<T> {
private final ManagedType managedType;
private final Class<T> subclass;

View File

@ -0,0 +1,5 @@
/**
* Definition of the Hibernate support for the JPA {@link javax.persistence.EntityGraph} feature-set
* introduced in JPA 2.1
*/
package org.hibernate.jpa.graph;

View File

@ -0,0 +1,39 @@
/*
* 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.jpa.graph.spi;
import javax.persistence.metamodel.Attribute;
import org.hibernate.jpa.HibernateEntityManagerFactory;
/**
* @author Steve Ebersole
*/
public interface AttributeNodeImplementor<T> {
public HibernateEntityManagerFactory entityManagerFactory();
public Attribute<?,T> getAttribute();
public AttributeNodeImplementor<T> makeImmutableCopy();
}

View File

@ -0,0 +1,107 @@
/*
* 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.jpa.graph.spi;
import java.util.List;
import org.jboss.logging.Logger;
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.LoadPlanAdvisor;
/**
* @author Steve Ebersole
*/
public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
private static final Logger log = Logger.getLogger( EntityGraphBasedLoadPlanAdvisor.class );
private final EntityGraphImpl root;
public EntityGraphBasedLoadPlanAdvisor(EntityGraphImpl root) {
if ( root == null ) {
throw new IllegalArgumentException( "EntityGraph cannot be null" );
}
this.root = root;
}
public LoadPlan advise(LoadPlan loadPlan) {
if ( root == null ) {
log.debug( "Skipping load plan advising: no entity graph was specified" );
}
else {
// for now, lets assume that the graph and the load-plan returns have to match up
EntityReturn entityReturn = findRootEntityReturn( loadPlan );
if ( entityReturn == null ) {
log.debug( "Skipping load plan advising: not able to find appropriate root entity return in load plan" );
}
else {
final String entityName = entityReturn.getEntityPersister().getEntityName();
if ( ! root.appliesTo( entityName ) ) {
log.debugf(
"Skipping load plan advising: entity types did not match : [%s] and [%s]",
root.getEntityType().getName(),
entityName
);
}
else {
// ok to apply the advice
return applyAdvice( entityReturn );
}
}
}
// return the original load-plan
return loadPlan;
}
private LoadPlan applyAdvice(final EntityReturn entityReturn) {
// final EntityReturn copy = entityReturn.makeCopy( )
return null;
}
private EntityReturn findRootEntityReturn(LoadPlan loadPlan) {
EntityReturn rootEntityReturn = null;
for ( Return rtn : loadPlan.getReturns() ) {
if ( ! EntityReturn.class.isInstance( rtn ) ) {
continue;
}
if ( rootEntityReturn != null ) {
log.debug( "Multiple EntityReturns were found" );
return null;
}
rootEntityReturn = (EntityReturn) rtn;
}
if ( rootEntityReturn == null ) {
log.debug( "Unable to find root entity return in load plan" );
}
return rootEntityReturn;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.jpa.graph.spi;
import javax.persistence.AttributeNode;
import java.util.List;
import org.hibernate.jpa.HibernateEntityManagerFactory;
/**
* Extended contract for a "graph node" (entity-graph or sub-graph).
*
* @author Steve Ebersole
*/
public interface GraphNodeImplementor {
public HibernateEntityManagerFactory entityManagerFactory();
public List<AttributeNode<?>> attributeNodes();
}

View File

@ -34,7 +34,6 @@ import javax.persistence.Query;
import javax.persistence.SynchronizationType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceUnitTransactionType;
@ -70,7 +69,8 @@ import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.HibernateQuery;
import org.hibernate.jpa.boot.internal.SettingsImpl;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
import org.hibernate.jpa.internal.graph.EntityGraphImpl;
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
import org.hibernate.jpa.internal.metamodel.EntityTypeImpl;
import org.hibernate.jpa.internal.metamodel.MetamodelImpl;
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
import org.hibernate.mapping.PersistentClass;
@ -95,7 +95,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
private final transient boolean discardOnClose;
private final transient Class sessionInterceptorClass;
private final transient CriteriaBuilderImpl criteriaBuilder;
private final transient Metamodel metamodel;
private final transient MetamodelImpl metamodel;
private final transient HibernatePersistenceUnitUtil util;
private final transient Map<String,Object> properties;
private final String entityManagerFactoryName;
@ -388,6 +388,15 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
return sessionFactory;
}
@Override
public EntityTypeImpl getEntityTypeByName(String entityName) {
final EntityTypeImpl entityType = metamodel.getEntityTypeByName( entityName );
if ( entityType == null ) {
throw new IllegalArgumentException( "[" + entityName + "] did not refer to EntityType" );
}
return entityType;
}
public String getEntityManagerFactoryName() {
return entityManagerFactoryName;
}

View File

@ -42,7 +42,7 @@ import org.hibernate.engine.spi.SessionBuilderImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SessionOwner;
import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.internal.graph.EntityGraphImpl;
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
/**
* Hibernate implementation of {@link javax.persistence.EntityManager}.

View File

@ -229,4 +229,8 @@ public class MetamodelImpl implements Metamodel, Serializable {
public Set<EmbeddableType<?>> getEmbeddables() {
return new HashSet<EmbeddableType<?>>( embeddables.values() );
}
public EntityTypeImpl getEntityTypeByName(String entityName) {
return entityTypesByEntityName.get( entityName );
}
}