/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.loadplans.plans;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.loader.plan.build.internal.CascadeStyleLoadPlanBuildingAssociationVisitationStrategy;
import org.hibernate.loader.plan.build.internal.FetchStyleLoadPlanBuildingAssociationVisitationStrategy;
import org.hibernate.loader.plan.build.spi.LoadPlanTreePrinter;
import org.hibernate.loader.plan.build.spi.MetamodelDrivenLoadPlanBuilder;
import org.hibernate.loader.plan.exec.internal.AliasResolutionContextImpl;
import org.hibernate.loader.plan.spi.CollectionReturn;
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.LoadPlan;
import org.hibernate.loader.plan.spi.Return;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.ExtraAssertions;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
/**
* @author Steve Ebersole
*/
public class LoadPlanBuilderTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Message.class, Poster.class };
}
@Test
public void testSimpleBuild() {
EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class);
FetchStyleLoadPlanBuildingAssociationVisitationStrategy strategy = new FetchStyleLoadPlanBuildingAssociationVisitationStrategy(
sessionFactory(),
LoadQueryInfluencers.NONE,
LockMode.NONE
);
LoadPlan plan = MetamodelDrivenLoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep );
assertFalse( plan.hasAnyScalarReturns() );
assertEquals( 1, plan.getReturns().size() );
Return rtn = plan.getReturns().get( 0 );
EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn );
assertNotNull( entityReturn.getFetches() );
assertEquals( 1, entityReturn.getFetches().length );
Fetch fetch = entityReturn.getFetches()[0];
EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch );
assertNotNull( entityFetch.getFetches() );
assertEquals( 0, entityFetch.getFetches().length );
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sessionFactory() ) );
}
@Test
public void testCascadeBasedBuild() {
EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class);
CascadeStyleLoadPlanBuildingAssociationVisitationStrategy strategy = new CascadeStyleLoadPlanBuildingAssociationVisitationStrategy(
CascadingActions.MERGE,
sessionFactory(),
LoadQueryInfluencers.NONE,
LockMode.NONE
);
LoadPlan plan = MetamodelDrivenLoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep );
assertFalse( plan.hasAnyScalarReturns() );
assertEquals( 1, plan.getReturns().size() );
Return rtn = plan.getReturns().get( 0 );
EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn );
assertNotNull( entityReturn.getFetches() );
assertEquals( 1, entityReturn.getFetches().length );
Fetch fetch = entityReturn.getFetches()[0];
EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch );
assertNotNull( entityFetch.getFetches() );
assertEquals( 0, entityFetch.getFetches().length );
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sessionFactory() ) );
}
@Test
public void testCollectionInitializerCase() {
CollectionPersister cp = sessionFactory().getCollectionPersister( Poster.class.getName() + ".messages" );
FetchStyleLoadPlanBuildingAssociationVisitationStrategy strategy = new FetchStyleLoadPlanBuildingAssociationVisitationStrategy(
sessionFactory(),
LoadQueryInfluencers.NONE,
LockMode.NONE
);
LoadPlan plan = MetamodelDrivenLoadPlanBuilder.buildRootCollectionLoadPlan( strategy, cp );
assertFalse( plan.hasAnyScalarReturns() );
assertEquals( 1, plan.getReturns().size() );
Return rtn = plan.getReturns().get( 0 );
CollectionReturn collectionReturn = ExtraAssertions.assertTyping( CollectionReturn.class, rtn );
assertNotNull( collectionReturn.getElementGraph() );
assertNotNull( collectionReturn.getElementGraph().getFetches() );
// the collection Message elements are fetched, but Message.poster is not fetched
// (because that collection is owned by that Poster)
assertEquals( 0, collectionReturn.getElementGraph().getFetches().length );
EntityReference entityReference = ExtraAssertions.assertTyping( EntityReference.class, collectionReturn.getElementGraph() );
assertNotNull( entityReference.getFetches() );
assertEquals( 0, entityReference.getFetches().length );
LoadPlanTreePrinter.INSTANCE.logTree( plan, new AliasResolutionContextImpl( sessionFactory() ) );
}
@Entity( name = "Message" )
public static class Message {
@Id
private Integer mid;
private String msgTxt;
@ManyToOne( cascade = CascadeType.MERGE )
@JoinColumn
private Poster poster;
}
@Entity( name = "Poster" )
public static class Poster {
@Id
private Integer pid;
private String name;
@OneToMany(mappedBy = "poster")
private List<Message> messages;
}
}