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.EntityFetch;
import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.LoadQueryBuilder; import org.hibernate.loader.spi.LoadQueryBuilder;
import org.hibernate.persister.entity.OuterJoinLoadable; 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.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityReference; import org.hibernate.loader.plan.spi.EntityReference;
import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.loader.spi.AfterLoadAction;
import org.hibernate.loader.spi.NamedParameterContext; import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.ResultSetProcessingContext; 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.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlan;
import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter;
import org.hibernate.loader.plan.spi.LoadPlanVisitor; import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor;
import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.plan.spi.Return;
import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.loader.spi.AfterLoadAction;
import org.hibernate.loader.spi.LoadPlanAdvisor;
import org.hibernate.loader.spi.NamedParameterContext; import org.hibernate.loader.spi.NamedParameterContext;
import org.hibernate.loader.spi.ScrollableResultSetProcessor; import org.hibernate.loader.spi.ScrollableResultSetProcessor;
import org.hibernate.loader.spi.ResultSetProcessor; import org.hibernate.loader.spi.ResultSetProcessor;
@ -58,12 +59,12 @@ import org.hibernate.transform.ResultTransformer;
public class ResultSetProcessorImpl implements ResultSetProcessor { public class ResultSetProcessorImpl implements ResultSetProcessor {
private static final Logger LOG = Logger.getLogger( ResultSetProcessorImpl.class ); private static final Logger LOG = Logger.getLogger( ResultSetProcessorImpl.class );
private final LoadPlan loadPlan; private final LoadPlan baseLoadPlan;
private final boolean hadSubselectFetches; private final boolean hadSubselectFetches;
public ResultSetProcessorImpl(LoadPlan loadPlan) { public ResultSetProcessorImpl(LoadPlan loadPlan) {
this.loadPlan = loadPlan; this.baseLoadPlan = loadPlan;
LocalVisitationStrategy strategy = new LocalVisitationStrategy(); LocalVisitationStrategy strategy = new LocalVisitationStrategy();
LoadPlanVisitor.visit( loadPlan, strategy ); LoadPlanVisitor.visit( loadPlan, strategy );
@ -78,6 +79,7 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
@Override @Override
public List extractResults( public List extractResults(
LoadPlanAdvisor loadPlanAdvisor,
ResultSet resultSet, ResultSet resultSet,
final SessionImplementor session, final SessionImplementor session,
QueryParameters queryParameters, QueryParameters queryParameters,
@ -87,7 +89,9 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
ResultTransformer forcedResultTransformer, ResultTransformer forcedResultTransformer,
List<AfterLoadAction> afterLoadActionList) throws SQLException { 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 int maxRows;
final RowSelection selection = queryParameters.getRowSelection(); final RowSelection selection = queryParameters.getRowSelection();
@ -163,6 +167,7 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
private void handlePotentiallyEmptyCollectionRootReturns( private void handlePotentiallyEmptyCollectionRootReturns(
LoadPlan loadPlan,
Serializable[] collectionKeys, Serializable[] collectionKeys,
ResultSet resultSet, ResultSet resultSet,
SessionImplementor session) { 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.CompositeFetch;
import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.loader.plan.spi.FetchOwner; 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.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; 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.CollectionAliases;
import org.hibernate.loader.EntityAliases; import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath; 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.CollectionReturn;
import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.EntityReturn;
import org.hibernate.loader.plan.spi.LoadPlan; 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.loader.plan.spi.Return;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; 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 CollectionAliases collectionAliases;
private final EntityAliases elementEntityAliases; private final EntityAliases elementEntityAliases;
private final FetchOwner indexGraph; private final FetchableCollectionIndex indexGraph;
private final FetchOwner elementGraph; private final FetchableCollectionElement elementGraph;
protected AbstractCollectionReference( protected AbstractCollectionReference(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
@ -67,7 +67,7 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
this.elementGraph = buildElementGraph( getCollectionPersister() ); this.elementGraph = buildElementGraph( getCollectionPersister() );
} }
private FetchOwner buildIndexGraph(CollectionPersister persister) { private FetchableCollectionIndex buildIndexGraph(CollectionPersister persister) {
if ( persister.hasIndex() ) { if ( persister.hasIndex() ) {
final Type type = persister.getIndexType(); final Type type = persister.getIndexType();
if ( type.isAssociationType() ) { if ( type.isAssociationType() ) {
@ -83,7 +83,7 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
return null; return null;
} }
private FetchOwner buildElementGraph(CollectionPersister persister) { private FetchableCollectionElement buildElementGraph(CollectionPersister persister) {
final Type type = persister.getElementType(); final Type type = persister.getElementType();
if ( type.isAssociationType() ) { if ( type.isAssociationType() ) {
if ( type.isEntityType() ) { if ( type.isEntityType() ) {
@ -97,6 +97,20 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple
return null; 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 @Override
public PropertyPath getPropertyPath() { public PropertyPath getPropertyPath() {
return propertyPath; return propertyPath;

View File

@ -24,14 +24,12 @@
package org.hibernate.loader.plan.spi; package org.hibernate.loader.plan.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.spi.ResultSetProcessingContext;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -45,10 +43,39 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) { public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) {
super( factory ); super( factory );
this.alias = alias; this.alias = alias;
this.lockMode = lockMode;
validate();
}
private void validate() {
if ( alias == null ) { if ( alias == null ) {
throw new HibernateException( "alias must be specified" ); 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() { public String getAlias() {

View File

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

View File

@ -57,6 +57,17 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
this.propertyPath = owner.getPropertyPath().append( ownerProperty ); 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 @Override
public FetchOwner getOwner() { public FetchOwner getOwner() {
return owner; return owner;

View File

@ -66,6 +66,12 @@ public class CollectionFetch extends AbstractCollectionReference implements Fetc
fetchOwner.addFetch( this ); fetchOwner.addFetch( this );
} }
protected CollectionFetch(CollectionFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext );
this.fetchOwner = fetchOwnerCopy;
this.fetchStrategy = original.fetchStrategy;
}
@Override @Override
public FetchOwner getOwner() { public FetchOwner getOwner() {
return fetchOwner; return fetchOwner;
@ -90,4 +96,12 @@ public class CollectionFetch extends AbstractCollectionReference implements Fetc
public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
return null; //To change body of implemented methods use File | Settings | File Templates. 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 * @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 ownerEntityName;
private final String ownerProperty; private final String ownerProperty;
@ -61,6 +61,12 @@ public class CollectionReturn extends AbstractCollectionReference implements Ret
this.ownerProperty = ownerProperty; 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. * Returns the class owning the collection.
* *
@ -98,4 +104,9 @@ public class CollectionReturn extends AbstractCollectionReference implements Ret
public String toString() { public String toString() {
return "CollectionReturn(" + getCollectionPersister().getRole() + ")"; 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; package org.hibernate.loader.plan.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -8,6 +9,7 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -16,12 +18,13 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class CompositeElementGraph extends AbstractPlanNode implements FetchOwner { public class CompositeElementGraph extends AbstractPlanNode implements FetchableCollectionElement {
private final CollectionReference collectionReference; private final CollectionReference collectionReference;
private final PropertyPath propertyPath; private final PropertyPath propertyPath;
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
private List<Fetch> fetches; private List<Fetch> fetches;
public CompositeElementGraph( public CompositeElementGraph(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
CollectionReference collectionReference, CollectionReference collectionReference,
@ -33,6 +36,26 @@ public class CompositeElementGraph extends AbstractPlanNode implements FetchOwne
this.propertyPath = collectionPath.append( "<elements>" ); 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 @Override
public void addFetch(Fetch fetch) { public void addFetch(Fetch fetch) {
if ( fetches == null ) { if ( fetches == null ) {
@ -89,4 +112,9 @@ public class CompositeElementGraph extends AbstractPlanNode implements FetchOwne
LoadPlanBuildingContext loadPlanBuildingContext) { LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, 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.FetchStyle;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -50,6 +51,10 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN ); super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN );
} }
public CompositeFetch(CompositeFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
super( original, copyContext, fetchOwnerCopy );
}
@Override @Override
public EntityPersister retrieveFetchSourcePersister() { public EntityPersister retrieveFetchSourcePersister() {
return getOwner().retrieveFetchSourcePersister(); return getOwner().retrieveFetchSourcePersister();
@ -86,4 +91,12 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
return null; //To change body of implemented methods use File | Settings | File Templates. 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; package org.hibernate.loader.plan.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -8,6 +9,7 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -16,7 +18,7 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner { public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex {
private final CollectionReference collectionReference; private final CollectionReference collectionReference;
private final PropertyPath propertyPath; private final PropertyPath propertyPath;
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
@ -33,6 +35,26 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner
this.propertyPath = propertyPath.append( "<index>" ); 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 @Override
public void addFetch(Fetch fetch) { public void addFetch(Fetch fetch) {
if ( fetches == null ) { if ( fetches == null ) {
@ -89,4 +111,9 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner
LoadPlanBuildingContext loadPlanBuildingContext) { LoadPlanBuildingContext loadPlanBuildingContext) {
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, 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; package org.hibernate.loader.plan.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
@ -9,6 +10,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases; import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -18,7 +20,7 @@ import org.hibernate.type.AssociationType;
/** /**
* @author Steve Ebersole * @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 CollectionReference collectionReference;
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
private final AssociationType elementType; private final AssociationType elementType;
@ -42,6 +44,29 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchOwner,
this.propertyPath = collectionPath.append( "<elements>" ); 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 @Override
public String getAlias() { public String getAlias() {
return null; return null;
@ -139,6 +164,11 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchOwner,
this.identifierDescription = identifierDescription; this.identifierDescription = identifierDescription;
} }
@Override
public EntityElementGraph makeCopy(CopyContext copyContext) {
return new EntityElementGraph( this, copyContext );
}
@Override @Override
public String toString() { public String toString() {
return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")"; 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.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases; import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.type.AssociationType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
/** /**
@ -70,6 +70,20 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() ); 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() { public EntityType getAssociationType() {
return associationType; return associationType;
} }
@ -262,4 +276,12 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
public String toString() { public String toString() {
return "EntityFetch(" + getPropertyPath().getFullPath() + " -> " + persister.getEntityName() + ")"; 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; package org.hibernate.loader.plan.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
@ -32,6 +33,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.EntityAliases; import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -41,7 +43,7 @@ import org.hibernate.type.AssociationType;
/** /**
* @author Steve Ebersole * @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 CollectionReference collectionReference;
private final CollectionPersister collectionPersister; private final CollectionPersister collectionPersister;
private final AssociationType indexType; 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? 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 @Override
public String getAlias() { public String getAlias() {
return null; return null;
@ -160,4 +184,9 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, En
public void injectIdentifierDescription(IdentifierDescription identifierDescription) { public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
this.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; package org.hibernate.loader.plan.spi;
import org.hibernate.AssertionFailure;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.loader.EntityAliases; import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
@ -35,7 +33,8 @@ import org.hibernate.persister.entity.EntityPersister;
* *
* @author Steve Ebersole * @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). * 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.EntityAliases;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
@ -44,7 +45,7 @@ import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierReso
/** /**
* @author Steve Ebersole * @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 EntityAliases entityAliases;
private final String sqlTableAlias; private final String sqlTableAlias;
@ -69,6 +70,13 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
this.persister = sessionFactory.getEntityPersister( entityName ); 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 @Override
public String getAlias() { public String getAlias() {
return super.getAlias(); return super.getAlias();
@ -205,4 +213,9 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
public String toString() { public String toString() {
return "EntityReturn(" + persister.getEntityName() + ")"; 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 * @author Steve Ebersole
*/ */
public interface Fetch { public interface Fetch extends CopyableFetch {
/** /**
* Obtain the owner of this fetch. * Obtain the owner of this fetch.
* *
@ -64,4 +64,7 @@ public interface Fetch {
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException;
public Object resolve(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.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
@ -91,4 +92,5 @@ public interface FetchOwner {
CompositionDefinition attributeDefinition, CompositionDefinition attributeDefinition,
LoadPlanBuildingContext loadPlanBuildingContext); 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 * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.loader.plan.spi; package org.hibernate.loader.plan.spi.build;
import java.io.Serializable; import java.io.Serializable;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -48,6 +48,17 @@ import org.hibernate.loader.EntityAliases;
import org.hibernate.loader.GeneratedCollectionAliases; import org.hibernate.loader.GeneratedCollectionAliases;
import org.hibernate.loader.PropertyPath; import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; 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.loader.spi.ResultSetProcessingContext;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;

View File

@ -21,14 +21,15 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; 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} * {@link LoadPlanBuilderStrategy}
* *
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -21,12 +21,13 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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; 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 * @author Steve Ebersole
*/ */

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.CollectionAliases; 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 * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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 * @author Steve Ebersole
*/ */
public class LoadPlanVisitationStrategyAdapter implements LoadPlanVisitationStrategy { public class LoadPlanVisitationStrategyAdapter implements LoadPlanVisitationStrategy {
public static final LoadPlanVisitationStrategyAdapter INSTANCE = new LoadPlanVisitationStrategyAdapter();
@Override @Override
public void start(LoadPlan loadPlan) { public void start(LoadPlan loadPlan) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finish(LoadPlan loadPlan) { public void finish(LoadPlan loadPlan) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void startingRootReturn(Return rootReturn) { public void startingRootReturn(Return rootReturn) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finishingRootReturn(Return rootReturn) { public void finishingRootReturn(Return rootReturn) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void handleScalarReturn(ScalarReturn scalarReturn) { public void handleScalarReturn(ScalarReturn scalarReturn) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void handleEntityReturn(EntityReturn rootEntityReturn) { public void handleEntityReturn(EntityReturn rootEntityReturn) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { public void handleCollectionReturn(CollectionReturn rootCollectionReturn) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void startingFetches(FetchOwner fetchOwner) { public void startingFetches(FetchOwner fetchOwner) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finishingFetches(FetchOwner fetchOwner) { public void finishingFetches(FetchOwner fetchOwner) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void startingEntityFetch(EntityFetch entityFetch) { public void startingEntityFetch(EntityFetch entityFetch) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finishingEntityFetch(EntityFetch entityFetch) { public void finishingEntityFetch(EntityFetch entityFetch) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void startingCollectionFetch(CollectionFetch collectionFetch) { public void startingCollectionFetch(CollectionFetch collectionFetch) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finishingCollectionFetch(CollectionFetch collectionFetch) { public void finishingCollectionFetch(CollectionFetch collectionFetch) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void startingCompositeFetch(CompositeFetch fetch) { public void startingCompositeFetch(CompositeFetch fetch) {
//To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void finishingCompositeFetch(CompositeFetch fetch) { 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 * 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 * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,25 +21,26 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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 * @author Steve Ebersole
*/ */
public interface LoadPlanVisitationStrategy { public interface ReturnGraphVisitationStrategy {
/** /**
* Notification we are preparing to start visitation. * 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>
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>
* <li>{@link #handleScalarReturn}</li> * <li>{@link #handleScalarReturn}</li>
* <li>{@link #handleEntityReturn}</li> * <li>{@link #handleEntityReturn}</li>
* <li>{@link #handleCollectionReturn}</li> * <li>{@link #handleCollectionReturn}</li>
@ -57,8 +58,8 @@ public interface LoadPlanVisitationStrategy {
public void finishingRootReturn(Return rootReturn); public void finishingRootReturn(Return rootReturn);
/** /**
* Notification that a scalar return is being processed. Will be surrounded by calls to {@link #startingRootReturn} * Notification that a scalar return is being processed. Will be surrounded by calls to
* and {@link #finishingRootReturn} * {@link #startingRootReturn} and {@link #finishingRootReturn}
* *
* @param scalarReturn The scalar return * @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 * 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 * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,32 +21,40 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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 * @author Steve Ebersole
*/ */
public class LoadPlanVisitor { public class ReturnGraphVisitor {
public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) { private final ReturnGraphVisitationStrategy strategy;
new LoadPlanVisitor( strategy ).visit( loadPlan );
}
private final LoadPlanVisitationStrategy strategy; public ReturnGraphVisitor(ReturnGraphVisitationStrategy strategy) {
public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) {
this.strategy = strategy; this.strategy = strategy;
} }
private void visit(LoadPlan loadPlan) { public void visit(Return... rootReturns) {
strategy.start( loadPlan ); for ( Return rootReturn : rootReturns ) {
for ( Return rootReturn : loadPlan.getReturns() ) {
visitRootReturn( rootReturn ); visitRootReturn( rootReturn );
} }
}
strategy.finish( loadPlan ); public void visit(List<Return> rootReturns) {
for ( Return rootReturn : rootReturns ) {
visitRootReturn( rootReturn );
}
} }
private void visitRootReturn(Return 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. * 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 resultSet The result set being processed.
* @param session The originating session * @param session The originating session
* @param queryParameters The "parameters" used to build the query * @param queryParameters The "parameters" used to build the query
* @param returnProxies Can proxies be returned (not the same as can they be created!) * @param returnProxies Can proxies be returned (not the same as can they be created!)
* @param forcedResultTransformer My old "friend" ResultTransformer... * @param forcedResultTransformer My old "friend" ResultTransformer...
* @param afterLoadActions Actions to be performed after loading an entity.
* *
* @return The extracted results list. * @return The extracted results list.
* *
* @throws java.sql.SQLException Indicates a problem access the JDBC ResultSet * @throws java.sql.SQLException Indicates a problem access the JDBC ResultSet
*/ */
public List extractResults( public List extractResults(
LoadPlanAdvisor loadPlanAdvisor,
ResultSet resultSet, ResultSet resultSet,
SessionImplementor session, SessionImplementor session,
QueryParameters queryParameters, 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.CascadeEntityLoader;
import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.EntityLoader;
import org.hibernate.loader.entity.UniqueEntityLoader; 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.Column;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
@ -130,10 +127,6 @@ import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template; import org.hibernate.sql.Template;
import org.hibernate.sql.Update; 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.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.AssociationType; 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.internal.ResultSetProcessorImpl;
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
import org.hibernate.loader.plan.spi.LoadPlan; 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.NamedParameterContext;
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.ExtraAssertions; import org.hibernate.testing.junit4.ExtraAssertions;
@ -114,6 +115,7 @@ public class EntityAssociationResultSetProcessorTest extends BaseCoreFunctionalT
ResultSet resultSet = ps.executeQuery(); ResultSet resultSet = ps.executeQuery();
results.addAll( results.addAll(
resultSetProcessor.extractResults( resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet, resultSet,
(SessionImplementor) workSession, (SessionImplementor) workSession,
new QueryParameters(), new QueryParameters(),
@ -207,6 +209,7 @@ public class EntityAssociationResultSetProcessorTest extends BaseCoreFunctionalT
ResultSet resultSet = ps.executeQuery(); ResultSet resultSet = ps.executeQuery();
results.addAll( results.addAll(
resultSetProcessor.extractResults( resultSetProcessor.extractResults(
NoOpLoadPlanAdvisor.INSTANCE,
resultSet, resultSet,
(SessionImplementor) workSession, (SessionImplementor) workSession,
new QueryParameters(), new QueryParameters(),

View File

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

View File

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

View File

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

View File

@ -27,6 +27,7 @@ import javax.persistence.EntityManagerFactory;
import java.io.Serializable; import java.io.Serializable;
import org.hibernate.SessionFactory; 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} * 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 * @return The underlying Hibernate SessionFactory
*/ */
public SessionFactory getSessionFactory(); public SessionFactory getSessionFactory();
public EntityTypeImpl getEntityTypeByName(String entityName);
} }

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.internal.graph; package org.hibernate.jpa.graph.internal;
import javax.persistence.AttributeNode; import javax.persistence.AttributeNode;
import javax.persistence.Subgraph; import javax.persistence.Subgraph;
@ -34,7 +34,7 @@ import org.hibernate.jpa.HibernateEntityManagerFactory;
/** /**
* @author Steve Ebersole * @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 ManagedType managedType;
private final Class<T> subclass; 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.SynchronizationType;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.EntityType; import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel; import javax.persistence.metamodel.Metamodel;
import javax.persistence.spi.LoadState; import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceUnitTransactionType; import javax.persistence.spi.PersistenceUnitTransactionType;
@ -70,7 +69,8 @@ import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.HibernateQuery; import org.hibernate.jpa.HibernateQuery;
import org.hibernate.jpa.boot.internal.SettingsImpl; import org.hibernate.jpa.boot.internal.SettingsImpl;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl; 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.metamodel.MetamodelImpl;
import org.hibernate.jpa.internal.util.PersistenceUtilHelper; import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
@ -95,7 +95,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
private final transient boolean discardOnClose; private final transient boolean discardOnClose;
private final transient Class sessionInterceptorClass; private final transient Class sessionInterceptorClass;
private final transient CriteriaBuilderImpl criteriaBuilder; private final transient CriteriaBuilderImpl criteriaBuilder;
private final transient Metamodel metamodel; private final transient MetamodelImpl metamodel;
private final transient HibernatePersistenceUnitUtil util; private final transient HibernatePersistenceUnitUtil util;
private final transient Map<String,Object> properties; private final transient Map<String,Object> properties;
private final String entityManagerFactoryName; private final String entityManagerFactoryName;
@ -388,6 +388,15 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
return sessionFactory; 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() { public String getEntityManagerFactoryName() {
return entityManagerFactoryName; 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.SessionImplementor;
import org.hibernate.engine.spi.SessionOwner; import org.hibernate.engine.spi.SessionOwner;
import org.hibernate.jpa.AvailableSettings; 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}. * Hibernate implementation of {@link javax.persistence.EntityManager}.

View File

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