HHH-7841 - Redesign Loader
This commit is contained in:
parent
b8b9735cf5
commit
3600ffb7f2
|
@ -90,6 +90,9 @@ public class ResultSetProcessorImpl implements ResultSetProcessor {
|
|||
List<AfterLoadAction> afterLoadActionList) throws SQLException {
|
||||
|
||||
final LoadPlan loadPlan = loadPlanAdvisor.advise( this.baseLoadPlan );
|
||||
if ( loadPlan == null ) {
|
||||
throw new IllegalStateException( "LoadPlanAdvisor returned null" );
|
||||
}
|
||||
|
||||
handlePotentiallyEmptyCollectionRootReturns( loadPlan, queryParameters.getCollectionKeys(), resultSet, session );
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public class CompositeFetch extends AbstractSingularAttributeFetch {
|
|||
public CompositeFetch(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
AbstractFetchOwner owner,
|
||||
FetchOwner owner,
|
||||
String ownerProperty) {
|
||||
super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN );
|
||||
}
|
||||
|
|
|
@ -26,8 +26,24 @@ package org.hibernate.loader.spi;
|
|||
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||
|
||||
/**
|
||||
* An advisor that can be made available to the {@link ResultSetProcessor} and {@link ScrollableResultSetProcessor}.
|
||||
*
|
||||
* The processors consult with the advisor, if one is provided, as a means to influence the load plan, meaning that
|
||||
* the advisor might add fetches. A caveat is that any added fetches cannot be join fetches (they cannot alter the
|
||||
* SQL); if a fetch is added as {@link org.hibernate.engine.FetchTiming#IMMEDIATE}, it must be a "subsequent form":
|
||||
* {@link org.hibernate.engine.FetchStyle#SELECT}, {@link org.hibernate.engine.FetchStyle#SUBSELECT},
|
||||
* {@link org.hibernate.engine.FetchStyle#BATCH}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LoadPlanAdvisor {
|
||||
/**
|
||||
* Advise on the given LoadPlan, returning a new LoadPlan if any additions are needed. It is the responsibility
|
||||
* of the advisor to return the original load plan if no additions were needed
|
||||
*
|
||||
* @param loadPlan The load plan to advise on.
|
||||
*
|
||||
* @return The original or advised load plan.
|
||||
*/
|
||||
public LoadPlan advise(LoadPlan loadPlan);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.loader.plan.spi.Fetch;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AdviceHelper {
|
||||
private AdviceHelper() {
|
||||
}
|
||||
|
||||
static Fetch buildFetch(FetchOwner fetchOwner, AttributeNodeImplementor attributeNode) {
|
||||
if ( attributeNode.getAttribute().isAssociation() ) {
|
||||
if ( attributeNode.getAttribute().isCollection() ) {
|
||||
return new CollectionFetch(
|
||||
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
|
||||
"abc-xyz", // alias
|
||||
LockMode.NONE,
|
||||
fetchOwner,
|
||||
new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.SELECT ),
|
||||
attributeNode.getAttributeName(),
|
||||
null, // sql table alias
|
||||
null // entityaliases
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new EntityFetch(
|
||||
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
|
||||
"abc-xyz", // alias
|
||||
LockMode.NONE,
|
||||
fetchOwner,
|
||||
attributeNode.getAttributeName(),
|
||||
new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.SELECT ),
|
||||
null, // sql table alias
|
||||
null // entityaliases
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return new CompositeFetch(
|
||||
(SessionFactoryImplementor) attributeNode.entityManagerFactory().getSessionFactory(),
|
||||
"abc-xyz", // alias
|
||||
fetchOwner,
|
||||
attributeNode.getAttributeName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
/**
|
||||
* Links together the LoadPlan graph and JPA graph notions of the same node.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
interface AdviceNodeDescriptor {
|
||||
public JpaGraphReference attributeProcessed(String attributeName);
|
||||
|
||||
public void applyMissingFetches();
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AdviceNodeDescriptorCollectionReference implements AdviceNodeDescriptor {
|
||||
private final CollectionFetch collectionFetch;
|
||||
private final JpaGraphReference jpaGraphReference;
|
||||
|
||||
public AdviceNodeDescriptorCollectionReference(
|
||||
CollectionFetch collectionFetch,
|
||||
JpaGraphReference jpaGraphReference) {
|
||||
//To change body of created methods use File | Settings | File Templates.
|
||||
this.collectionFetch = collectionFetch;
|
||||
this.jpaGraphReference = jpaGraphReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
return jpaGraphReference != null
|
||||
? jpaGraphReference.attributeProcessed( attributeName )
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches() {
|
||||
if ( jpaGraphReference == null ) {
|
||||
return;
|
||||
}
|
||||
jpaGraphReference.applyMissingFetches( collectionFetch.getElementGraph() );
|
||||
( (JpaGraphCollectionReference) jpaGraphReference ).applyMissingKeyFetches( collectionFetch.getIndexGraph() );
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AdviceNodeDescriptorCompositeReference implements AdviceNodeDescriptor {
|
||||
private final FetchOwner fetchOwner;
|
||||
private final JpaGraphReference jpaGraphReference;
|
||||
|
||||
AdviceNodeDescriptorCompositeReference(CompositeFetch fetchOwner, JpaGraphReference jpaGraphReference) {
|
||||
this.fetchOwner = fetchOwner;
|
||||
this.jpaGraphReference = jpaGraphReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
return jpaGraphReference != null
|
||||
? jpaGraphReference.attributeProcessed( attributeName )
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches() {
|
||||
if ( jpaGraphReference != null ) {
|
||||
jpaGraphReference.applyMissingFetches( fetchOwner );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* An AdviceNodeDescriptor that represents an entity reference
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class AdviceNodeDescriptorEntityReference implements AdviceNodeDescriptor {
|
||||
private final FetchOwner fetchOwner;
|
||||
private final JpaGraphReference jpaGraphReference;
|
||||
|
||||
AdviceNodeDescriptorEntityReference(EntityReturn fetchOwner, JpaGraphReference jpaGraphReference) {
|
||||
this.fetchOwner = fetchOwner;
|
||||
this.jpaGraphReference = jpaGraphReference;
|
||||
}
|
||||
|
||||
AdviceNodeDescriptorEntityReference(EntityFetch fetchOwner, JpaGraphReference jpaGraphReference) {
|
||||
this.fetchOwner = fetchOwner;
|
||||
this.jpaGraphReference = jpaGraphReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
return jpaGraphReference != null
|
||||
? jpaGraphReference.attributeProcessed( attributeName )
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches() {
|
||||
if ( jpaGraphReference != null ) {
|
||||
jpaGraphReference.applyMissingFetches( fetchOwner );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.internal.advisor;
|
||||
|
||||
/** The style of advice. This is defined by the JPA spec. See tha values for details.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public enum AdviceStyle {
|
||||
/**
|
||||
* Indicates a graph specified by the {@code javax.persistence.fetchgraph} setting.
|
||||
*/
|
||||
FETCH,
|
||||
/**
|
||||
* Indicates a graph specified by the {@code javax.persistence.loadgraph} setting.
|
||||
*/
|
||||
LOAD
|
||||
}
|
|
@ -23,29 +23,20 @@
|
|||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.internal.LoadPlanImpl;
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.CopyContext;
|
||||
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.visit.ReturnGraphVisitationStrategy;
|
||||
import org.hibernate.loader.plan.spi.visit.ReturnGraphVisitationStrategyAdapter;
|
||||
import org.hibernate.loader.spi.LoadPlanAdvisor;
|
||||
|
||||
/**
|
||||
* A LoadPlanAdvisor implementation for applying JPA "entity graph" fetches
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
|
||||
|
@ -54,6 +45,13 @@ public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
|
|||
private final EntityGraphImpl root;
|
||||
private final AdviceStyle adviceStyle;
|
||||
|
||||
/**
|
||||
* Constricts a LoadPlanAdvisor for applying any additional fetches needed as indicated by the
|
||||
* given entity graph.
|
||||
*
|
||||
* @param root The entity graph indicating the fetches.
|
||||
* @param adviceStyle The style of advise (this is defikned
|
||||
*/
|
||||
public EntityGraphBasedLoadPlanAdvisor(EntityGraphImpl root, AdviceStyle adviceStyle) {
|
||||
if ( root == null ) {
|
||||
throw new IllegalArgumentException( "EntityGraph cannot be null" );
|
||||
|
@ -62,6 +60,7 @@ public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
|
|||
this.adviceStyle = adviceStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadPlan advise(LoadPlan loadPlan) {
|
||||
if ( root == null ) {
|
||||
log.debug( "Skipping load plan advising: no entity graph was specified" );
|
||||
|
@ -119,16 +118,11 @@ public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
|
|||
return rootEntityReturn;
|
||||
}
|
||||
|
||||
public static enum AdviceStyle {
|
||||
FETCH,
|
||||
LOAD
|
||||
}
|
||||
|
||||
public class CopyContextImpl implements CopyContext {
|
||||
private final ReturnGraphVisitationStrategyImpl strategy;
|
||||
|
||||
public CopyContextImpl(EntityReturn entityReturn) {
|
||||
strategy = new ReturnGraphVisitationStrategyImpl( entityReturn );
|
||||
strategy = new ReturnGraphVisitationStrategyImpl( entityReturn, root );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,157 +131,4 @@ public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor {
|
|||
}
|
||||
}
|
||||
|
||||
public class ReturnGraphVisitationStrategyImpl extends ReturnGraphVisitationStrategyAdapter {
|
||||
private ArrayDeque<NodeDescriptor> nodeStack = new ArrayDeque<NodeDescriptor>();
|
||||
|
||||
public ReturnGraphVisitationStrategyImpl(EntityReturn entityReturn) {
|
||||
nodeStack.addFirst( new EntityReferenceDescriptor( entityReturn, new RootEntityGraphNode( root ) ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingRootReturn(Return rootReturn) {
|
||||
nodeStack.removeFirst();
|
||||
super.finishingRootReturn( rootReturn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingFetches(FetchOwner fetchOwner) {
|
||||
nodeStack.peekFirst().applyMissingFetches();
|
||||
super.finishingFetches( fetchOwner );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingEntityFetch(EntityFetch entityFetch) {
|
||||
super.startingEntityFetch( entityFetch );
|
||||
|
||||
final NodeDescriptor currentNode = nodeStack.peekFirst();
|
||||
final String attributeName = entityFetch.getOwnerPropertyName();
|
||||
final JpaGraphReference fetchedGraphReference = currentNode.attributeProcessed( attributeName );
|
||||
nodeStack.addFirst( new EntityReferenceDescriptor( entityFetch, fetchedGraphReference ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingEntityFetch(EntityFetch entityFetch) {
|
||||
nodeStack.removeFirst();
|
||||
super.finishingEntityFetch( entityFetch );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCollectionFetch(CollectionFetch collectionFetch) {
|
||||
super.startingCollectionFetch( collectionFetch ); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollectionFetch(CollectionFetch collectionFetch) {
|
||||
super.finishingCollectionFetch( collectionFetch ); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCompositeFetch(CompositeFetch fetch) {
|
||||
super.startingCompositeFetch( fetch ); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCompositeFetch(CompositeFetch fetch) {
|
||||
super.finishingCompositeFetch( fetch ); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
private static interface NodeDescriptor {
|
||||
public JpaGraphReference attributeProcessed(String attributeName);
|
||||
|
||||
public void applyMissingFetches();
|
||||
}
|
||||
|
||||
private static abstract class AbstractNodeDescriptor implements NodeDescriptor {
|
||||
private final FetchOwner fetchOwner;
|
||||
private final JpaGraphReference jpaGraphReference;
|
||||
|
||||
protected AbstractNodeDescriptor(FetchOwner fetchOwner, JpaGraphReference jpaGraphReference) {
|
||||
this.fetchOwner = fetchOwner;
|
||||
this.jpaGraphReference = jpaGraphReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
if ( jpaGraphReference != null ) {
|
||||
return jpaGraphReference.attributeProcessed( attributeName );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches() {
|
||||
if ( jpaGraphReference != null ) {
|
||||
jpaGraphReference.applyMissingFetches( fetchOwner );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntityReferenceDescriptor extends AbstractNodeDescriptor {
|
||||
private EntityReferenceDescriptor(EntityReturn entityReturn, JpaGraphReference correspondingJpaGraphNode) {
|
||||
super( entityReturn, correspondingJpaGraphNode );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityReferenceDescriptor(EntityFetch entityFetch, JpaGraphReference jpaGraphReference) {
|
||||
super( entityFetch, jpaGraphReference );
|
||||
}
|
||||
}
|
||||
|
||||
private static interface JpaGraphReference {
|
||||
public JpaGraphReference attributeProcessed(String attributeName);
|
||||
public void applyMissingFetches(FetchOwner fetchOwner);
|
||||
}
|
||||
|
||||
private static class RootEntityGraphNode implements JpaGraphReference {
|
||||
private final Map<String,AttributeNodeImplementor> graphAttributeMap;
|
||||
|
||||
private RootEntityGraphNode(EntityGraphImpl entityGraph) {
|
||||
graphAttributeMap = new HashMap<String, AttributeNodeImplementor>();
|
||||
|
||||
final List<AttributeNodeImplementor<?>> explicitAttributeNodes = entityGraph.attributeImplementorNodes();
|
||||
if ( explicitAttributeNodes != null ) {
|
||||
for ( AttributeNodeImplementor node : explicitAttributeNodes ) {
|
||||
graphAttributeMap.put( node.getAttributeName(), node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
final AttributeNodeImplementor attributeNode = graphAttributeMap.remove( attributeName );
|
||||
|
||||
if ( attributeNode == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SubGraphNode( attributeNode );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
for ( AttributeNodeImplementor attributeNode : graphAttributeMap.values() ) {
|
||||
System.out.println( "Found unprocessed attribute node : " + attributeNode.getAttributeName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SubGraphNode implements JpaGraphReference {
|
||||
protected SubGraphNode(AttributeNodeImplementor attributeNode) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class JpaGraphCollectionReference extends JpaGraphReferenceSubGraphSupport {
|
||||
private final AttributeNodeImplementor<?> attributeNode;
|
||||
|
||||
JpaGraphCollectionReference(AttributeNodeImplementor<?> attributeNode) {
|
||||
super( attributeNode );
|
||||
this.attributeNode = attributeNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
super.applyMissingFetches( fetchOwner );
|
||||
// todo : additionally we need to process key graph(s)
|
||||
}
|
||||
|
||||
void applyMissingKeyFetches(FetchOwner fetchOwner) {
|
||||
// todo : additionally we need to process key graph(s)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* Describes a reference to a JPA graph. This encompasses both {@link javax.persistence.EntityGraph}
|
||||
* and {@link javax.persistence.Subgraph}. Exposes the functionality needed for advising in a common way.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
interface JpaGraphReference {
|
||||
/**
|
||||
* Callback to let the JPA graph reference node know that the particular attribute (by name) was processed, which
|
||||
* means it already was accounted for in the LoadPlan graph. For association attributes and composites, also
|
||||
* returns a representation of the corresponding JPA graph node.
|
||||
*
|
||||
* @param attributeName The name of the attribute processed.
|
||||
*
|
||||
* @return The JPA graph reference corresponding to that attribute, if one.
|
||||
*/
|
||||
public JpaGraphReference attributeProcessed(String attributeName);
|
||||
|
||||
/**
|
||||
* For any attributes that are defined in the JPA graph, that were not processed (as would have been indicated
|
||||
* by a previous call to {@link #attributeProcessed}), apply needed fetches to the fetch owner.
|
||||
*
|
||||
* @param fetchOwner The owner of any generated fetches.
|
||||
*/
|
||||
public void applyMissingFetches(FetchOwner fetchOwner);
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import javax.persistence.AttributeNode;
|
||||
import javax.persistence.Subgraph;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
abstract class JpaGraphReferenceSubGraphSupport implements JpaGraphReference {
|
||||
private static final Logger log = Logger.getLogger( JpaGraphReferenceSubGraphSupport.class );
|
||||
|
||||
private final Map<String,AttributeNodeImplementor> elementGraphAttributeMap;
|
||||
|
||||
|
||||
protected JpaGraphReferenceSubGraphSupport(AttributeNodeImplementor<?> attributeNode) {
|
||||
this.elementGraphAttributeMap = new HashMap<String, AttributeNodeImplementor>();
|
||||
|
||||
for ( Subgraph<?> subgraph : attributeNode.getSubgraphs().values() ) {
|
||||
for ( AttributeNode<?> subGraphAttributeNode : subgraph.getAttributeNodes() ) {
|
||||
final AttributeNodeImplementor<?> nodeImplementor = (AttributeNodeImplementor<?>) subGraphAttributeNode;
|
||||
final AttributeNodeImplementor<?> old = this.elementGraphAttributeMap.put(
|
||||
nodeImplementor.getAttributeName(),
|
||||
nodeImplementor
|
||||
);
|
||||
|
||||
if ( old != null && old != nodeImplementor ) {
|
||||
throw new IllegalStateException(
|
||||
"Found multiple representations of the same attribute : " + nodeImplementor.getAttributeName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
final AttributeNodeImplementor attributeNode = this.elementGraphAttributeMap.remove( attributeName );
|
||||
|
||||
if ( attributeNode == null ) {
|
||||
return NoOpJpaGraphReference.INSTANCE;
|
||||
}
|
||||
|
||||
return attributeNode.getAttribute().isCollection()
|
||||
? new JpaGraphCollectionReference( attributeNode )
|
||||
: new JpaGraphSingularAttributeReference( attributeNode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
for ( AttributeNodeImplementor attributeNode : elementGraphAttributeMap.values() ) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"Found unprocessed attribute node [%s], applying to fetch-owner [%s]",
|
||||
attributeNode.getAttributeName(),
|
||||
fetchOwner.getPropertyPath().getFullPath()
|
||||
)
|
||||
);
|
||||
|
||||
log.tracef(
|
||||
"Found unprocessed attribute node [%s], applying to fetch-owner [%s]",
|
||||
attributeNode.getAttributeName(),
|
||||
fetchOwner.getPropertyPath()
|
||||
);
|
||||
|
||||
AdviceHelper.buildFetch( fetchOwner, attributeNode );
|
||||
|
||||
// todo : additionally we need to process any further graphs in the attribute node path
|
||||
// since we are effectively at a leaf in the LoadPlan graph
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* Models the root {@link javax.persistence.EntityGraph} as a JpaGraphReference
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class JpaGraphRootEntityReference implements JpaGraphReference {
|
||||
private static final Logger log = Logger.getLogger( JpaGraphRootEntityReference.class );
|
||||
|
||||
private final Map<String,AttributeNodeImplementor> graphAttributeMap;
|
||||
|
||||
JpaGraphRootEntityReference(EntityGraphImpl entityGraph) {
|
||||
graphAttributeMap = new HashMap<String, AttributeNodeImplementor>();
|
||||
|
||||
final List<AttributeNodeImplementor<?>> explicitAttributeNodes = entityGraph.attributeImplementorNodes();
|
||||
if ( explicitAttributeNodes != null ) {
|
||||
for ( AttributeNodeImplementor node : explicitAttributeNodes ) {
|
||||
graphAttributeMap.put( node.getAttributeName(), node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
final AttributeNodeImplementor attributeNode = graphAttributeMap.remove( attributeName );
|
||||
|
||||
if ( attributeNode == null ) {
|
||||
return NoOpJpaGraphReference.INSTANCE;
|
||||
}
|
||||
|
||||
return attributeNode.getAttribute().isCollection()
|
||||
? new JpaGraphCollectionReference( attributeNode )
|
||||
: new JpaGraphSingularAttributeReference( attributeNode );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
for ( AttributeNodeImplementor attributeNode : graphAttributeMap.values() ) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"Found unprocessed attribute node [%s], applying to fetch-owner [%s]",
|
||||
attributeNode.getAttributeName(),
|
||||
fetchOwner.getPropertyPath().getFullPath()
|
||||
)
|
||||
);
|
||||
|
||||
log.tracef(
|
||||
"Found unprocessed attribute node [%s], applying to fetch-owner [%s]",
|
||||
attributeNode.getAttributeName(),
|
||||
fetchOwner.getPropertyPath()
|
||||
);
|
||||
|
||||
AdviceHelper.buildFetch( fetchOwner, attributeNode );
|
||||
|
||||
// todo : additionally we need to process any further graphs in the attribute node path
|
||||
// since we are effectively at a leaf in the LoadPlan graph
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.graph.internal.advisor;
|
||||
|
||||
import org.hibernate.jpa.graph.spi.AttributeNodeImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class JpaGraphSingularAttributeReference extends JpaGraphReferenceSubGraphSupport {
|
||||
JpaGraphSingularAttributeReference(AttributeNodeImplementor attributeNode) {
|
||||
super( attributeNode );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
|
||||
/**
|
||||
* A no-op implementation of JpaGraphReference. Used when the LoadPlan graph already defines
|
||||
* nodes beyond the scope of the JPA graph.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class NoOpJpaGraphReference implements JpaGraphReference {
|
||||
public static final NoOpJpaGraphReference INSTANCE = new NoOpJpaGraphReference();
|
||||
|
||||
@Override
|
||||
public JpaGraphReference attributeProcessed(String attributeName) {
|
||||
// its no-op, nothing to do
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMissingFetches(FetchOwner fetchOwner) {
|
||||
// its no-op, nothing to do
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.internal.advisor;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
import org.hibernate.jpa.graph.internal.EntityGraphImpl;
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
import org.hibernate.loader.plan.spi.Return;
|
||||
import org.hibernate.loader.plan.spi.visit.ReturnGraphVisitationStrategyAdapter;
|
||||
|
||||
/**
|
||||
* The visitor strategy for visiting the return graph of the load plan being advised.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ReturnGraphVisitationStrategyImpl extends ReturnGraphVisitationStrategyAdapter {
|
||||
private ArrayDeque<AdviceNodeDescriptor> nodeStack = new ArrayDeque<AdviceNodeDescriptor>();
|
||||
|
||||
public ReturnGraphVisitationStrategyImpl(EntityReturn entityReturn, EntityGraphImpl jpaRoot) {
|
||||
nodeStack.addFirst( new AdviceNodeDescriptorEntityReference( entityReturn, new JpaGraphRootEntityReference( jpaRoot ) ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingRootReturn(Return rootReturn) {
|
||||
nodeStack.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingFetches(FetchOwner fetchOwner) {
|
||||
nodeStack.peekFirst().applyMissingFetches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingEntityFetch(EntityFetch entityFetch) {
|
||||
final AdviceNodeDescriptor currentNode = nodeStack.peekFirst();
|
||||
final String attributeName = entityFetch.getOwnerPropertyName();
|
||||
final JpaGraphReference fetchedGraphReference = currentNode.attributeProcessed( attributeName );
|
||||
|
||||
nodeStack.addFirst( new AdviceNodeDescriptorEntityReference( entityFetch, fetchedGraphReference ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingEntityFetch(EntityFetch entityFetch) {
|
||||
nodeStack.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCollectionFetch(CollectionFetch collectionFetch) {
|
||||
final AdviceNodeDescriptor currentNode = nodeStack.peekFirst();
|
||||
final String attributeName = collectionFetch.getOwnerPropertyName();
|
||||
final JpaGraphReference fetchedGraphReference = currentNode.attributeProcessed( attributeName );
|
||||
|
||||
nodeStack.addFirst( new AdviceNodeDescriptorCollectionReference( collectionFetch, fetchedGraphReference ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollectionFetch(CollectionFetch collectionFetch) {
|
||||
nodeStack.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCompositeFetch(CompositeFetch fetch) {
|
||||
final AdviceNodeDescriptor currentNode = nodeStack.peekFirst();
|
||||
final String attributeName = fetch.getOwnerPropertyName();
|
||||
final JpaGraphReference fetchedGraphReference = currentNode.attributeProcessed( attributeName );
|
||||
|
||||
nodeStack.addFirst( new AdviceNodeDescriptorCompositeReference( fetch, fetchedGraphReference ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCompositeFetch(CompositeFetch fetch) {
|
||||
nodeStack.removeFirst();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009, 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -20,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.internal.metamodel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Member;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
@ -86,58 +89,43 @@ public class SingularAttributeImpl<X, Y>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isId() {
|
||||
return isIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isVersion() {
|
||||
return isVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return isOptional;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Type<Y> getType() {
|
||||
return attributeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return false;
|
||||
return getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE
|
||||
|| getPersistentAttributeType() == PersistentAttributeType.ONE_TO_ONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isCollection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public BindableType getBindableType() {
|
||||
return BindableType.SINGULAR_ATTRIBUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<Y> getBindableJavaType() {
|
||||
return attributeType.getJavaType();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.hibernate.persister.entity.Loadable;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.jpa.graph.internal.advisor.EntityGraphBasedLoadPlanAdvisor.AdviceStyle;
|
||||
import org.hibernate.jpa.graph.internal.advisor.AdviceStyle;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
|
Loading…
Reference in New Issue