HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
This commit is contained in:
parent
b10c51eec7
commit
f32c736160
|
@ -49,6 +49,7 @@ public abstract class BatchingEntityLoaderBuilder {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return org.hibernate.loader.entity.plan.LegacyBatchingEntityLoaderBuilder.INSTANCE;
|
return org.hibernate.loader.entity.plan.LegacyBatchingEntityLoaderBuilder.INSTANCE;
|
||||||
|
// return LegacyBatchingEntityLoaderBuilder.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,32 +309,32 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
// - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite
|
// - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
// public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
||||||
log.tracef(
|
// log.tracef(
|
||||||
"%s Starting composite collection element for (%s)",
|
// "%s Starting composite collection element for (%s)",
|
||||||
StringHelper.repeat( ">>", fetchOwnerStack.size() ),
|
// StringHelper.repeat( ">>", fetchOwnerStack.size() ),
|
||||||
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
// compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
// public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
||||||
// pop the current fetch owner, and make sure what we just popped represents this composition
|
// // pop the current fetch owner, and make sure what we just popped represents this composition
|
||||||
final FetchOwner poppedFetchOwner = popFromStack();
|
// final FetchOwner poppedFetchOwner = popFromStack();
|
||||||
|
//
|
||||||
if ( ! CompositeElementGraph.class.isInstance( poppedFetchOwner ) ) {
|
// if ( ! CompositeElementGraph.class.isInstance( poppedFetchOwner ) ) {
|
||||||
throw new WalkingException( "Mismatched FetchOwner from stack on pop" );
|
// throw new WalkingException( "Mismatched FetchOwner from stack on pop" );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// NOTE : not much else we can really check here atm since on the walking spi side we do not have path
|
// // NOTE : not much else we can really check here atm since on the walking spi side we do not have path
|
||||||
|
//
|
||||||
log.tracef(
|
// log.tracef(
|
||||||
"%s Finished composite element for : %s",
|
// "%s Finished composite element for : %s",
|
||||||
StringHelper.repeat( "<<", fetchOwnerStack.size() ),
|
// StringHelper.repeat( "<<", fetchOwnerStack.size() ),
|
||||||
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
// compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
||||||
|
|
|
@ -39,21 +39,14 @@ public abstract class AbstractCompositeEntityIdentifierDescription
|
||||||
implements EntityIdentifierDescription, FetchSource, ExpandingEntityIdentifierDescription {
|
implements EntityIdentifierDescription, FetchSource, ExpandingEntityIdentifierDescription {
|
||||||
|
|
||||||
private final EntityReference entityReference;
|
private final EntityReference entityReference;
|
||||||
private final CompositeQuerySpace compositeQuerySpace;
|
|
||||||
|
|
||||||
protected AbstractCompositeEntityIdentifierDescription(
|
protected AbstractCompositeEntityIdentifierDescription(
|
||||||
EntityReference entityReference,
|
EntityReference entityReference,
|
||||||
CompositeQuerySpace compositeQuerySpace,
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
CompositeType identifierType,
|
CompositeType identifierType,
|
||||||
PropertyPath propertyPath) {
|
PropertyPath propertyPath) {
|
||||||
super( identifierType, propertyPath );
|
super( identifierType, compositeQuerySpace, false, propertyPath );
|
||||||
this.entityReference = entityReference;
|
this.entityReference = entityReference;
|
||||||
this.compositeQuerySpace = compositeQuerySpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFetchLeftHandSideUid() {
|
|
||||||
return compositeQuerySpace.getUid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,11 +59,4 @@ public abstract class AbstractCompositeEntityIdentifierDescription
|
||||||
// the source for this (as a Fetch) is the entity reference
|
// the source for this (as a Fetch) is the entity reference
|
||||||
return (FetchSource) entityReference.getIdentifierDescription();
|
return (FetchSource) entityReference.getIdentifierDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQuerySpaceUid() {
|
|
||||||
return compositeQuerySpace.getUid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
|
||||||
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
|
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
|
||||||
import org.hibernate.loader.plan2.spi.CollectionFetch;
|
import org.hibernate.loader.plan2.spi.CollectionFetch;
|
||||||
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
||||||
|
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
|
||||||
import org.hibernate.loader.plan2.spi.EntityFetch;
|
import org.hibernate.loader.plan2.spi.EntityFetch;
|
||||||
import org.hibernate.loader.plan2.spi.Fetch;
|
import org.hibernate.loader.plan2.spi.Fetch;
|
||||||
import org.hibernate.loader.plan2.spi.Join;
|
import org.hibernate.loader.plan2.spi.Join;
|
||||||
|
@ -56,16 +57,31 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
|
||||||
private static final FetchStrategy FETCH_STRATEGY = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
private static final FetchStrategy FETCH_STRATEGY = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||||
|
|
||||||
private final CompositeType compositeType;
|
private final CompositeType compositeType;
|
||||||
|
private final CompositeQuerySpace compositeQuerySpace;
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
|
private final boolean allowCollectionFetches;
|
||||||
|
|
||||||
private List<Fetch> fetches;
|
private List<Fetch> fetches;
|
||||||
|
|
||||||
protected AbstractCompositeFetch(CompositeType compositeType, PropertyPath propertyPath) {
|
protected AbstractCompositeFetch(
|
||||||
|
CompositeType compositeType,
|
||||||
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
|
boolean allowCollectionFetches, PropertyPath propertyPath) {
|
||||||
this.compositeType = compositeType;
|
this.compositeType = compositeType;
|
||||||
|
this.compositeQuerySpace = compositeQuerySpace;
|
||||||
|
this.allowCollectionFetches = allowCollectionFetches;
|
||||||
this.propertyPath = propertyPath;
|
this.propertyPath = propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getFetchLeftHandSideUid();
|
@SuppressWarnings("UnusedParameters")
|
||||||
|
protected CompositeQuerySpace resolveCompositeQuerySpace(LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
return compositeQuerySpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQuerySpaceUid() {
|
||||||
|
return compositeQuerySpace.getUid();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateFetchPlan(FetchStrategy fetchStrategy, AttributeDefinition attributeDefinition) {
|
public void validateFetchPlan(FetchStrategy fetchStrategy, AttributeDefinition attributeDefinition) {
|
||||||
|
@ -92,8 +108,8 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) loadPlanBuildingContext.getQuerySpaces().getQuerySpaceByUid(
|
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) resolveCompositeQuerySpace(
|
||||||
getFetchLeftHandSideUid()
|
loadPlanBuildingContext
|
||||||
);
|
);
|
||||||
final Join join = leftHandSide.addEntityJoin(
|
final Join join = leftHandSide.addEntityJoin(
|
||||||
attributeDefinition,
|
attributeDefinition,
|
||||||
|
@ -122,11 +138,18 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
|
||||||
public CompositeFetch buildCompositeFetch(
|
public CompositeFetch buildCompositeFetch(
|
||||||
CompositionDefinition attributeDefinition,
|
CompositionDefinition attributeDefinition,
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) resolveCompositeQuerySpace( loadPlanBuildingContext );
|
||||||
|
final Join join = leftHandSide.addCompositeJoin(
|
||||||
|
attributeDefinition,
|
||||||
|
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
|
||||||
|
);
|
||||||
|
|
||||||
final NestedCompositeFetchImpl fetch = new NestedCompositeFetchImpl(
|
final NestedCompositeFetchImpl fetch = new NestedCompositeFetchImpl(
|
||||||
this,
|
this,
|
||||||
attributeDefinition.getType(),
|
attributeDefinition.getType(),
|
||||||
getPropertyPath(),
|
(CompositeQuerySpace) join.getRightHandSide(),
|
||||||
getFetchLeftHandSideUid()
|
allowCollectionFetches,
|
||||||
|
getPropertyPath()
|
||||||
);
|
);
|
||||||
addFetch( fetch );
|
addFetch( fetch );
|
||||||
return fetch;
|
return fetch;
|
||||||
|
@ -137,6 +160,15 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
AssociationAttributeDefinition attributeDefinition,
|
||||||
FetchStrategy fetchStrategy,
|
FetchStrategy fetchStrategy,
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
if ( !allowCollectionFetches ) {
|
||||||
|
throw new WalkingException(
|
||||||
|
String.format(
|
||||||
|
"This composite path [%s] does not allow collection fetches (composite id or composite collection index/element",
|
||||||
|
propertyPath.getFullPath()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// general question here wrt Joins and collection fetches... do we create multiple Joins for many-to-many,
|
// general question here wrt Joins and collection fetches... do we create multiple Joins for many-to-many,
|
||||||
// for example, or do we allow the Collection QuerySpace to handle that?
|
// for example, or do we allow the Collection QuerySpace to handle that?
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
|
||||||
PropertyPath propertyPath) {
|
PropertyPath propertyPath) {
|
||||||
this.entityQuerySpace = entityQuerySpace;
|
this.entityQuerySpace = entityQuerySpace;
|
||||||
this.propertyPath = propertyPath;
|
this.propertyPath = propertyPath;
|
||||||
this.identifierDescription = buildIdentifierDescription( entityQuerySpace );
|
this.identifierDescription = buildIdentifierDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,11 +77,9 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
|
||||||
* Builds just the first level of identifier description. This will be either a simple id descriptor (String,
|
* Builds just the first level of identifier description. This will be either a simple id descriptor (String,
|
||||||
* Long, etc) or some form of composite id (either encapsulated or not).
|
* Long, etc) or some form of composite id (either encapsulated or not).
|
||||||
*
|
*
|
||||||
* @param querySpace The entity query space
|
|
||||||
*
|
|
||||||
* @return the descriptor for the identifier
|
* @return the descriptor for the identifier
|
||||||
*/
|
*/
|
||||||
private EntityIdentifierDescription buildIdentifierDescription(EntityQuerySpace querySpace) {
|
private EntityIdentifierDescription buildIdentifierDescription() {
|
||||||
final EntityPersister persister = entityQuerySpace.getEntityPersister();
|
final EntityPersister persister = entityQuerySpace.getEntityPersister();
|
||||||
final EntityIdentifierDefinition identifierDefinition = persister.getEntityKeyDefinition();
|
final EntityIdentifierDefinition identifierDefinition = persister.getEntityKeyDefinition();
|
||||||
|
|
||||||
|
@ -166,9 +164,8 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) loadPlanBuildingContext.getQuerySpaces().getQuerySpaceByUid(
|
|
||||||
getQuerySpaceUid()
|
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) entityQuerySpace;
|
||||||
);
|
|
||||||
final Join join = leftHandSide.addEntityJoin(
|
final Join join = leftHandSide.addEntityJoin(
|
||||||
attributeDefinition,
|
attributeDefinition,
|
||||||
fetchedPersister,
|
fetchedPersister,
|
||||||
|
@ -196,9 +193,17 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
|
||||||
public CompositeFetch buildCompositeFetch(
|
public CompositeFetch buildCompositeFetch(
|
||||||
CompositionDefinition attributeDefinition,
|
CompositionDefinition attributeDefinition,
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) entityQuerySpace;
|
||||||
|
final Join join = leftHandSide.addCompositeJoin(
|
||||||
|
attributeDefinition,
|
||||||
|
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
|
||||||
|
);
|
||||||
|
|
||||||
final CompositeFetchImpl fetch = new CompositeFetchImpl(
|
final CompositeFetchImpl fetch = new CompositeFetchImpl(
|
||||||
this,
|
this,
|
||||||
attributeDefinition.getType(),
|
attributeDefinition.getType(),
|
||||||
|
(CompositeQuerySpace) join.getRightHandSide(),
|
||||||
|
true,
|
||||||
getPropertyPath()
|
getPropertyPath()
|
||||||
);
|
);
|
||||||
addFetch( fetch );
|
addFetch( fetch );
|
||||||
|
|
|
@ -23,19 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.loader.plan2.build.internal.returns;
|
package org.hibernate.loader.plan2.build.internal.returns;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
|
||||||
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.loader.plan2.spi.CollectionFetch;
|
|
||||||
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
|
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
|
||||||
import org.hibernate.loader.plan2.spi.CollectionReference;
|
import org.hibernate.loader.plan2.spi.CollectionReference;
|
||||||
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
||||||
|
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
|
||||||
import org.hibernate.loader.plan2.spi.FetchSource;
|
import org.hibernate.loader.plan2.spi.FetchSource;
|
||||||
import org.hibernate.loader.plan2.spi.Join;
|
import org.hibernate.loader.plan2.spi.Join;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.WalkingException;
|
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Models the element graph of a collection, where the elements are composite
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CollectionFetchableElementCompositeGraph
|
public class CollectionFetchableElementCompositeGraph
|
||||||
|
@ -43,23 +41,16 @@ public class CollectionFetchableElementCompositeGraph
|
||||||
implements CompositeFetch, CollectionFetchableElement {
|
implements CompositeFetch, CollectionFetchableElement {
|
||||||
|
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final Join compositeJoin;
|
|
||||||
|
|
||||||
public CollectionFetchableElementCompositeGraph(
|
public CollectionFetchableElementCompositeGraph(CollectionReference collectionReference, Join compositeJoin) {
|
||||||
CollectionReference collectionReference,
|
|
||||||
Join compositeJoin) {
|
|
||||||
super(
|
super(
|
||||||
(CompositeType) compositeJoin.getRightHandSide().getPropertyMapping().getType(),
|
(CompositeType) compositeJoin.getRightHandSide().getPropertyMapping().getType(),
|
||||||
|
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
|
||||||
|
false,
|
||||||
// these property paths are just informational...
|
// these property paths are just informational...
|
||||||
collectionReference.getPropertyPath().append( "<element>" )
|
collectionReference.getPropertyPath().append( "<element>" )
|
||||||
);
|
);
|
||||||
this.collectionReference = collectionReference;
|
this.collectionReference = collectionReference;
|
||||||
this.compositeJoin = compositeJoin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFetchLeftHandSideUid() {
|
|
||||||
return compositeJoin.getRightHandSide().getUid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,17 +62,4 @@ public class CollectionFetchableElementCompositeGraph
|
||||||
public FetchSource getSource() {
|
public FetchSource getSource() {
|
||||||
return collectionReference.getElementGraph();
|
return collectionReference.getElementGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
throw new WalkingException( "Encountered collection as part of fetched Collection composite-element" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQuerySpaceUid() {
|
|
||||||
return compositeJoin.getLeftHandSide().getUid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,21 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.loader.plan2.build.internal.returns;
|
package org.hibernate.loader.plan2.build.internal.returns;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
|
||||||
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.loader.plan2.spi.CollectionFetch;
|
|
||||||
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
|
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
|
||||||
import org.hibernate.loader.plan2.spi.CollectionReference;
|
import org.hibernate.loader.plan2.spi.CollectionReference;
|
||||||
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
||||||
|
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
|
||||||
import org.hibernate.loader.plan2.spi.FetchSource;
|
import org.hibernate.loader.plan2.spi.FetchSource;
|
||||||
import org.hibernate.loader.plan2.spi.Join;
|
import org.hibernate.loader.plan2.spi.Join;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.WalkingException;
|
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Models the index graph of a collection, where the index are composite. This can only be a Map, where the keys are
|
||||||
|
* composite
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CollectionFetchableIndexCompositeGraph
|
public class CollectionFetchableIndexCompositeGraph
|
||||||
|
@ -45,17 +43,17 @@ public class CollectionFetchableIndexCompositeGraph
|
||||||
implements CompositeFetch, CollectionFetchableIndex {
|
implements CompositeFetch, CollectionFetchableIndex {
|
||||||
|
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final Join compositeJoin;
|
|
||||||
|
|
||||||
public CollectionFetchableIndexCompositeGraph(
|
public CollectionFetchableIndexCompositeGraph(
|
||||||
CollectionReference collectionReference,
|
CollectionReference collectionReference,
|
||||||
Join compositeJoin) {
|
Join compositeJoin) {
|
||||||
super(
|
super(
|
||||||
extractIndexType( compositeJoin ),
|
extractIndexType( compositeJoin ),
|
||||||
|
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
|
||||||
|
false,
|
||||||
collectionReference.getPropertyPath().append( "<index>" )
|
collectionReference.getPropertyPath().append( "<index>" )
|
||||||
);
|
);
|
||||||
this.collectionReference = collectionReference;
|
this.collectionReference = collectionReference;
|
||||||
this.compositeJoin = compositeJoin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CompositeType extractIndexType(Join compositeJoin) {
|
private static CompositeType extractIndexType(Join compositeJoin) {
|
||||||
|
@ -67,12 +65,6 @@ public class CollectionFetchableIndexCompositeGraph
|
||||||
throw new IllegalArgumentException( "Could note extract collection composite-index" );
|
throw new IllegalArgumentException( "Could note extract collection composite-index" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFetchLeftHandSideUid() {
|
|
||||||
return compositeJoin.getRightHandSide().getUid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollectionReference getCollectionReference() {
|
public CollectionReference getCollectionReference() {
|
||||||
return collectionReference;
|
return collectionReference;
|
||||||
|
@ -82,24 +74,4 @@ public class CollectionFetchableIndexCompositeGraph
|
||||||
public FetchSource getSource() {
|
public FetchSource getSource() {
|
||||||
return collectionReference.getIndexGraph();
|
return collectionReference.getIndexGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateFetchPlan(FetchStrategy fetchStrategy, AttributeDefinition attributeDefinition) {
|
|
||||||
// metamodel should already disallow collections to be defined as part of a collection composite-index
|
|
||||||
// so, nothing to do here
|
|
||||||
super.validateFetchPlan( fetchStrategy, attributeDefinition );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
throw new WalkingException( "Encountered collection as part of the Map composite-index" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQuerySpaceUid() {
|
|
||||||
return compositeJoin.getRightHandSide().getUid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ package org.hibernate.loader.plan2.build.internal.returns;
|
||||||
|
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
||||||
import org.hibernate.loader.plan2.spi.EntityReference;
|
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
|
||||||
import org.hibernate.loader.plan2.spi.FetchSource;
|
import org.hibernate.loader.plan2.spi.FetchSource;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
|
@ -33,28 +33,20 @@ import org.hibernate.type.CompositeType;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CompositeFetchImpl extends AbstractCompositeFetch implements CompositeFetch {
|
public class CompositeFetchImpl extends AbstractCompositeFetch implements CompositeFetch {
|
||||||
private final EntityReference source;
|
private final FetchSource source;
|
||||||
|
|
||||||
protected CompositeFetchImpl(
|
protected CompositeFetchImpl(
|
||||||
EntityReference source,
|
FetchSource source,
|
||||||
CompositeType compositeType,
|
CompositeType compositeType,
|
||||||
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
|
boolean allowCollectionFetches,
|
||||||
PropertyPath propertyPath) {
|
PropertyPath propertyPath) {
|
||||||
super( compositeType, propertyPath );
|
super( compositeType, compositeQuerySpace, allowCollectionFetches, propertyPath );
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFetchLeftHandSideUid() {
|
|
||||||
return getSource().getQuerySpaceUid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchSource getSource() {
|
public FetchSource getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQuerySpaceUid() {
|
|
||||||
return source.getQuerySpaceUid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,28 @@ import org.hibernate.loader.plan2.spi.EntityReference;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Models a composite entity identifier that is encapsulated (meaning there is a composite class and a single
|
||||||
|
* attribute that encapsulates the composite value).
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EncapsulatedEntityIdentifierDescription
|
public class EncapsulatedEntityIdentifierDescription
|
||||||
extends AbstractCompositeEntityIdentifierDescription
|
extends AbstractCompositeEntityIdentifierDescription
|
||||||
implements ExpandingEntityIdentifierDescription {
|
implements ExpandingEntityIdentifierDescription {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an encapsulated version of a composite EntityIdentifierDescription
|
||||||
|
*
|
||||||
|
* @param entityReference The entity whose identifier we describe
|
||||||
|
* @param compositeQuerySpace The query space we are mapped to.
|
||||||
|
* @param compositeType The type representing this composition
|
||||||
|
* @param propertyPath The property path (informational)
|
||||||
|
*/
|
||||||
protected EncapsulatedEntityIdentifierDescription(
|
protected EncapsulatedEntityIdentifierDescription(
|
||||||
EntityReference entityReference,
|
EntityReference entityReference,
|
||||||
CompositeQuerySpace compositeQuerySpace,
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
CompositeType identifierType, PropertyPath propertyPath) {
|
CompositeType compositeType,
|
||||||
super( entityReference, compositeQuerySpace, identifierType, propertyPath );
|
PropertyPath propertyPath) {
|
||||||
|
super( entityReference, compositeQuerySpace, compositeType, propertyPath );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.loader.plan2.build.internal.returns;
|
||||||
|
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
import org.hibernate.loader.plan2.spi.CompositeFetch;
|
||||||
|
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
|
||||||
import org.hibernate.loader.plan2.spi.FetchSource;
|
import org.hibernate.loader.plan2.spi.FetchSource;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
|
@ -33,30 +34,18 @@ import org.hibernate.type.CompositeType;
|
||||||
*/
|
*/
|
||||||
public class NestedCompositeFetchImpl extends AbstractCompositeFetch {
|
public class NestedCompositeFetchImpl extends AbstractCompositeFetch {
|
||||||
private final CompositeFetch source;
|
private final CompositeFetch source;
|
||||||
private final String fetchLeftHandSideUid;
|
|
||||||
|
|
||||||
public NestedCompositeFetchImpl(
|
public NestedCompositeFetchImpl(
|
||||||
CompositeFetch source,
|
CompositeFetch source,
|
||||||
CompositeType type,
|
CompositeType type,
|
||||||
PropertyPath propertyPath,
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
String fetchLeftHandSideUid) {
|
boolean allowCollectionFetches, PropertyPath propertyPath) {
|
||||||
super( type, propertyPath );
|
super( type, compositeQuerySpace, allowCollectionFetches, propertyPath );
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.fetchLeftHandSideUid = fetchLeftHandSideUid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFetchLeftHandSideUid() {
|
|
||||||
return fetchLeftHandSideUid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchSource getSource() {
|
public FetchSource getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQuerySpaceUid() {
|
|
||||||
return source.getQuerySpaceUid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,20 @@ import org.hibernate.loader.plan2.spi.EntityReference;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Models a composite entity identifier that is non-encapsulated (meaning there is no composite class, no
|
||||||
|
* single attribute that encapsulates the composite value).
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class NonEncapsulatedEntityIdentifierDescription extends AbstractCompositeEntityIdentifierDescription {
|
public class NonEncapsulatedEntityIdentifierDescription extends AbstractCompositeEntityIdentifierDescription {
|
||||||
|
/**
|
||||||
|
* Build a non-encapsulated version of a composite EntityIdentifierDescription
|
||||||
|
*
|
||||||
|
* @param entityReference The entity whose identifier we describe
|
||||||
|
* @param compositeQuerySpace The query space we are mapped to.
|
||||||
|
* @param compositeType The type representing this composition
|
||||||
|
* @param propertyPath The property path (informational)
|
||||||
|
*/
|
||||||
public NonEncapsulatedEntityIdentifierDescription(
|
public NonEncapsulatedEntityIdentifierDescription(
|
||||||
EntityReference entityReference,
|
EntityReference entityReference,
|
||||||
CompositeQuerySpace compositeQuerySpace,
|
CompositeQuerySpace compositeQuerySpace,
|
||||||
|
|
|
@ -58,7 +58,6 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
|
@ -201,7 +200,13 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
final ExpandingFetchSource fetchSource = popFromStack();
|
final ExpandingFetchSource fetchSource = popFromStack();
|
||||||
|
|
||||||
if ( ! EntityReference.class.isInstance( fetchSource ) ) {
|
if ( ! EntityReference.class.isInstance( fetchSource ) ) {
|
||||||
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
|
throw new WalkingException(
|
||||||
|
String.format(
|
||||||
|
"Mismatched FetchSource from stack on pop. Expecting EntityReference(%s), but found %s",
|
||||||
|
entityDefinition.getEntityPersister().getEntityName(),
|
||||||
|
fetchSource
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final EntityReference entityReference = (EntityReference) fetchSource;
|
final EntityReference entityReference = (EntityReference) fetchSource;
|
||||||
|
@ -366,39 +371,79 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) {
|
public void startingCollectionIndex(CollectionIndexDefinition indexDefinition) {
|
||||||
final Type indexType = collectionIndexDefinition.getType();
|
final Type indexType = indexDefinition.getType();
|
||||||
if ( indexType.isAssociationType() || indexType.isComponentType() ) {
|
if ( indexType.isAnyType() ) {
|
||||||
|
throw new WalkingException( "CollectionIndexDefinition reported any-type mapping as map index" );
|
||||||
|
}
|
||||||
|
|
||||||
|
log.tracef(
|
||||||
|
"%s Starting collection index graph : %s",
|
||||||
|
StringHelper.repeat( ">>", fetchSourceStack.size() ),
|
||||||
|
indexDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
|
|
||||||
final CollectionReference collectionReference = collectionReferenceStack.peekFirst();
|
final CollectionReference collectionReference = collectionReferenceStack.peekFirst();
|
||||||
final CollectionFetchableIndex indexGraph = collectionReference.getIndexGraph();
|
final CollectionFetchableIndex indexGraph = collectionReference.getIndexGraph();
|
||||||
|
|
||||||
|
if ( indexType.isEntityType() || indexType.isComponentType() ) {
|
||||||
if ( indexGraph == null ) {
|
if ( indexGraph == null ) {
|
||||||
throw new WalkingException( "Collection reference did not return index handler" );
|
throw new WalkingException(
|
||||||
|
"CollectionReference did not return an expected index graph : " +
|
||||||
|
indexDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
pushToStack( (ExpandingFetchSource) indexGraph );
|
pushToStack( (ExpandingFetchSource) indexGraph );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( indexGraph != null ) {
|
||||||
|
throw new WalkingException(
|
||||||
|
"CollectionReference returned an unexpected index graph : " +
|
||||||
|
indexDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) {
|
public void finishingCollectionIndex(CollectionIndexDefinition indexDefinition) {
|
||||||
// nothing to do here
|
final Type indexType = indexDefinition.getType();
|
||||||
// - the element graph pushed while starting would be popped in finishingEntity/finishingComposite
|
if ( indexType.isComponentType() ) {
|
||||||
|
// todo : validate the stack?
|
||||||
|
popFromStack();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// entity indexes would be popped during finishingEntity processing
|
||||||
|
|
||||||
|
log.tracef(
|
||||||
|
"%s Finished collection index graph : %s",
|
||||||
|
StringHelper.repeat( "<<", fetchSourceStack.size() ),
|
||||||
|
indexDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startingCollectionElements(CollectionElementDefinition elementDefinition) {
|
public void startingCollectionElements(CollectionElementDefinition elementDefinition) {
|
||||||
|
final Type elementType = elementDefinition.getType();
|
||||||
|
if ( elementType.isAnyType() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.tracef(
|
||||||
|
"%s Starting collection element graph : %s",
|
||||||
|
StringHelper.repeat( ">>", fetchSourceStack.size() ),
|
||||||
|
elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
|
|
||||||
final CollectionReference collectionReference = collectionReferenceStack.peekFirst();
|
final CollectionReference collectionReference = collectionReferenceStack.peekFirst();
|
||||||
final CollectionFetchableElement elementGraph = collectionReference.getElementGraph();
|
final CollectionFetchableElement elementGraph = collectionReference.getElementGraph();
|
||||||
|
|
||||||
final Type elementType = elementDefinition.getType();
|
if ( elementType.isAssociationType() || elementType.isComponentType() ) {
|
||||||
final boolean expectFetchSourceElements =
|
|
||||||
( elementType.isAssociationType() || elementType.isComponentType() )
|
|
||||||
&& ! elementType.isAnyType();
|
|
||||||
|
|
||||||
if ( expectFetchSourceElements ) {
|
|
||||||
if ( elementGraph == null ) {
|
if ( elementGraph == null ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Expecting CollectionFetchableElement, but element graph was null : "
|
"CollectionReference did not return an expected element graph : " +
|
||||||
+ elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,8 +452,8 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
else {
|
else {
|
||||||
if ( elementGraph != null ) {
|
if ( elementGraph != null ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Not expecting CollectionFetchableElement, but element graph was non-null : "
|
"CollectionReference returned an unexpected element graph : " +
|
||||||
+ elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,41 +461,31 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishingCollectionElements(CollectionElementDefinition elementDefinition) {
|
public void finishingCollectionElements(CollectionElementDefinition elementDefinition) {
|
||||||
// nothing to do here
|
final Type elementType = elementDefinition.getType();
|
||||||
// - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite
|
if ( elementType.isComponentType() ) {
|
||||||
}
|
// pop it from the stack
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
|
||||||
log.tracef(
|
|
||||||
"%s Starting composite collection element for (%s)",
|
|
||||||
StringHelper.repeat( ">>", fetchSourceStack.size() ),
|
|
||||||
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositeElementDefinition) {
|
|
||||||
// pop the current fetch owner, and make sure what we just popped represents this composition
|
|
||||||
final ExpandingFetchSource popped = popFromStack();
|
final ExpandingFetchSource popped = popFromStack();
|
||||||
|
|
||||||
|
// validation
|
||||||
|
|
||||||
if ( ! CollectionFetchableElement.class.isInstance( popped ) ) {
|
if ( ! CollectionFetchableElement.class.isInstance( popped ) ) {
|
||||||
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
|
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE : not much else we can really check here atm since on the walking spi side we do not have path
|
// entity indexes would be popped during finishingEntity processing
|
||||||
|
|
||||||
log.tracef(
|
log.tracef(
|
||||||
"%s Finished composite element for : %s",
|
"%s Finished collection element graph : %s",
|
||||||
StringHelper.repeat( "<<", fetchSourceStack.size() ),
|
StringHelper.repeat( "<<", fetchSourceStack.size() ),
|
||||||
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startingComposite(CompositionDefinition compositionDefinition) {
|
public void startingComposite(CompositionDefinition compositionDefinition) {
|
||||||
log.tracef(
|
log.tracef(
|
||||||
"%s Starting composition : %s",
|
"%s Starting composite : %s",
|
||||||
StringHelper.repeat( ">>", fetchSourceStack.size() ),
|
StringHelper.repeat( ">>", fetchSourceStack.size() ),
|
||||||
compositionDefinition.getName()
|
compositionDefinition.getName()
|
||||||
);
|
);
|
||||||
|
@ -458,6 +493,9 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
if ( fetchSourceStack.isEmpty() ) {
|
if ( fetchSourceStack.isEmpty() ) {
|
||||||
throw new HibernateException( "A component cannot be the root of a walk nor a graph" );
|
throw new HibernateException( "A component cannot be the root of a walk nor a graph" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final CompositeFetch compositeFetch = currentSource().buildCompositeFetch( compositionDefinition, this );
|
||||||
|
pushToStack( (ExpandingFetchSource) compositeFetch );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -469,10 +507,8 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
|
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE : not much else we can really check here atm since on the walking spi side we do not have path
|
|
||||||
|
|
||||||
log.tracef(
|
log.tracef(
|
||||||
"%s Finished composition : %s",
|
"%s Finishing composite : %s",
|
||||||
StringHelper.repeat( "<<", fetchSourceStack.size() ),
|
StringHelper.repeat( "<<", fetchSourceStack.size() ),
|
||||||
compositionDefinition.getName()
|
compositionDefinition.getName()
|
||||||
);
|
);
|
||||||
|
@ -672,9 +708,9 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean handleCompositeAttribute(CompositionDefinition attributeDefinition) {
|
protected boolean handleCompositeAttribute(CompositionDefinition attributeDefinition) {
|
||||||
final ExpandingFetchSource currentSource = currentSource();
|
// final ExpandingFetchSource currentSource = currentSource();
|
||||||
final CompositeFetch fetch = currentSource.buildCompositeFetch( attributeDefinition, this );
|
// final CompositeFetch fetch = currentSource.buildCompositeFetch( attributeDefinition, this );
|
||||||
pushToStack( (ExpandingFetchSource) fetch );
|
// pushToStack( (ExpandingFetchSource) fetch );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,10 @@ public class LoadQueryJoinAndFetchProcessor {
|
||||||
//
|
//
|
||||||
// long story short, for now we'll use an assumption that the last join in the CollectionQuerySpace is the
|
// long story short, for now we'll use an assumption that the last join in the CollectionQuerySpace is the
|
||||||
// element join (that's how the joins are built as of now..)
|
// element join (that's how the joins are built as of now..)
|
||||||
// todo : remove this assumption ^^
|
//
|
||||||
|
// todo : remove this assumption ^^; maybe we make CollectionQuerySpace "special" and rather than have it
|
||||||
|
// hold a list of joins, we have it expose the 2 (index, element) separately.
|
||||||
|
|
||||||
Join collectionElementJoin = null;
|
Join collectionElementJoin = null;
|
||||||
for ( Join collectionJoin : rightHandSide.getJoins() ) {
|
for ( Join collectionJoin : rightHandSide.getJoins() ) {
|
||||||
collectionElementJoin = collectionJoin;
|
collectionElementJoin = collectionJoin;
|
||||||
|
|
|
@ -49,7 +49,7 @@ public interface AssociationVisitationStrategy {
|
||||||
/**
|
/**
|
||||||
* Notification we are starting to walk an entity.
|
* Notification we are starting to walk an entity.
|
||||||
*
|
*
|
||||||
* @param entityDefinition The entity we are starting to walk
|
* @param entityDefinition The entity we are preparing to walk
|
||||||
*/
|
*/
|
||||||
public void startingEntity(EntityDefinition entityDefinition);
|
public void startingEntity(EntityDefinition entityDefinition);
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public interface AssociationVisitationStrategy {
|
||||||
/**
|
/**
|
||||||
* Notification we are starting to walk the identifier of an entity.
|
* Notification we are starting to walk the identifier of an entity.
|
||||||
*
|
*
|
||||||
* @param entityIdentifierDefinition The identifier we are starting to walk
|
* @param entityIdentifierDefinition The identifier we are preparing to walk
|
||||||
*/
|
*/
|
||||||
public void startingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition);
|
public void startingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition);
|
||||||
|
|
||||||
|
@ -74,22 +74,93 @@ public interface AssociationVisitationStrategy {
|
||||||
*/
|
*/
|
||||||
public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition);
|
public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are starting to walk a collection
|
||||||
|
*
|
||||||
|
* @param collectionDefinition The collection we are preparing to walk
|
||||||
|
*/
|
||||||
public void startingCollection(CollectionDefinition collectionDefinition);
|
public void startingCollection(CollectionDefinition collectionDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are finishing walking a collection
|
||||||
|
*
|
||||||
|
* @param collectionDefinition The collection we are finishing
|
||||||
|
*/
|
||||||
public void finishingCollection(CollectionDefinition collectionDefinition);
|
public void finishingCollection(CollectionDefinition collectionDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are starting to walk the index of a collection (List/Map). In the case of a Map,
|
||||||
|
* if the indices (the keys) are entities this will be followed up by a call to {@link #startingEntity}
|
||||||
|
*
|
||||||
|
* @param collectionIndexDefinition The collection index we are preparing to walk.
|
||||||
|
*/
|
||||||
public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition);
|
public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are finishing walking the index of a collection (List/Map).
|
||||||
|
*
|
||||||
|
* @param collectionIndexDefinition The collection index we are finishing
|
||||||
|
*/
|
||||||
public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition);
|
public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are starting to look at the element definition for the collection. If the collection
|
||||||
|
* elements are entities this will be followed up by a call to {@link #startingEntity}
|
||||||
|
*
|
||||||
|
* @param elementDefinition The collection element we are preparing to walk..
|
||||||
|
*/
|
||||||
public void startingCollectionElements(CollectionElementDefinition elementDefinition);
|
public void startingCollectionElements(CollectionElementDefinition elementDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are finishing walking the elements of a collection (List/Map).
|
||||||
|
*
|
||||||
|
* @param elementDefinition The collection element we are finishing
|
||||||
|
*/
|
||||||
public void finishingCollectionElements(CollectionElementDefinition elementDefinition);
|
public void finishingCollectionElements(CollectionElementDefinition elementDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are preparing to walk a composite. This is called only for:<ul>
|
||||||
|
* <li>
|
||||||
|
* top-level composites for entity attributes. composite entity identifiers do not route through here, see
|
||||||
|
* {@link #startingEntityIdentifier} if you need to hook into walking the top-level cid composite.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* All forms of nested composite paths
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param compositionDefinition The composite we are preparing to walk.
|
||||||
|
*/
|
||||||
public void startingComposite(CompositionDefinition compositionDefinition);
|
public void startingComposite(CompositionDefinition compositionDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are done walking a composite. Called on the back-end of the situations listed
|
||||||
|
* on {@link #startingComposite}
|
||||||
|
*
|
||||||
|
* @param compositionDefinition The composite we are finishing
|
||||||
|
*/
|
||||||
public void finishingComposite(CompositionDefinition compositionDefinition);
|
public void finishingComposite(CompositionDefinition compositionDefinition);
|
||||||
|
|
||||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
// get rid of these ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
// public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
||||||
|
// public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition);
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are preparing to walk an attribute. May be followed by calls to {@link #startingEntity}
|
||||||
|
* (one-to-one, many-to-one), {@link #startingComposite}, or {@link #startingCollection}.
|
||||||
|
*
|
||||||
|
* @param attributeDefinition The attribute we are preparing to walk.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the walking should continue; {@code false} if walking should stop.
|
||||||
|
*/
|
||||||
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that we are finishing walking an attribute.
|
||||||
|
*
|
||||||
|
* @param attributeDefinition The attribute we are done walking
|
||||||
|
*/
|
||||||
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
||||||
|
|
||||||
public void foundAny(AssociationAttributeDefinition attributeDefinition, AnyMappingDefinition anyDefinition);
|
public void foundAny(AssociationAttributeDefinition attributeDefinition, AnyMappingDefinition anyDefinition);
|
||||||
|
|
|
@ -118,6 +118,8 @@ public class MetamodelGraphWalker {
|
||||||
// to make encapsulated and non-encapsulated composite identifiers work the same here, we "cheat" here a
|
// to make encapsulated and non-encapsulated composite identifiers work the same here, we "cheat" here a
|
||||||
// little bit and simply walk the attributes of the composite id in both cases.
|
// little bit and simply walk the attributes of the composite id in both cases.
|
||||||
|
|
||||||
|
// this works because the LoadPlans already build the top-level composite for composite ids
|
||||||
|
|
||||||
if ( identifierDefinition.isEncapsulated() ) {
|
if ( identifierDefinition.isEncapsulated() ) {
|
||||||
// in the encapsulated composite id case that means we have a little bit of duplication between here and
|
// in the encapsulated composite id case that means we have a little bit of duplication between here and
|
||||||
// visitCompositeDefinition, but in the spirit of consistently handling composite ids, that is much better
|
// visitCompositeDefinition, but in the spirit of consistently handling composite ids, that is much better
|
||||||
|
@ -125,12 +127,12 @@ public class MetamodelGraphWalker {
|
||||||
final EncapsulatedEntityIdentifierDefinition idAsEncapsulated = (EncapsulatedEntityIdentifierDefinition) identifierDefinition;
|
final EncapsulatedEntityIdentifierDefinition idAsEncapsulated = (EncapsulatedEntityIdentifierDefinition) identifierDefinition;
|
||||||
final AttributeDefinition idAttr = idAsEncapsulated.getAttributeDefinition();
|
final AttributeDefinition idAttr = idAsEncapsulated.getAttributeDefinition();
|
||||||
if ( CompositionDefinition.class.isInstance( idAttr ) ) {
|
if ( CompositionDefinition.class.isInstance( idAttr ) ) {
|
||||||
visitCompositeDefinition( (CompositionDefinition) idAttr );
|
visitAttributes( (CompositionDefinition) idAttr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// NonEncapsulatedEntityIdentifierDefinition itself is defined as a CompositionDefinition
|
// NonEncapsulatedEntityIdentifierDefinition itself is defined as a CompositionDefinition
|
||||||
visitCompositeDefinition( (NonEncapsulatedEntityIdentifierDefinition) identifierDefinition );
|
visitAttributes( (NonEncapsulatedEntityIdentifierDefinition) identifierDefinition );
|
||||||
}
|
}
|
||||||
|
|
||||||
strategy.finishingEntityIdentifier( identifierDefinition );
|
strategy.finishingEntityIdentifier( identifierDefinition );
|
||||||
|
@ -252,7 +254,7 @@ public class MetamodelGraphWalker {
|
||||||
strategy.startingCollectionElements( elementDefinition );
|
strategy.startingCollectionElements( elementDefinition );
|
||||||
|
|
||||||
if ( elementDefinition.getType().isComponentType() ) {
|
if ( elementDefinition.getType().isComponentType() ) {
|
||||||
visitCompositeCollectionElementDefinition( elementDefinition.toCompositeElementDefinition() );
|
visitAttributes( elementDefinition.toCompositeElementDefinition() );
|
||||||
}
|
}
|
||||||
else if ( elementDefinition.getType().isEntityType() ) {
|
else if ( elementDefinition.getType().isEntityType() ) {
|
||||||
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
||||||
|
@ -261,14 +263,6 @@ public class MetamodelGraphWalker {
|
||||||
strategy.finishingCollectionElements( elementDefinition );
|
strategy.finishingCollectionElements( elementDefinition );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitCompositeCollectionElementDefinition(CompositeCollectionElementDefinition compositionElementDefinition) {
|
|
||||||
strategy.startingCompositeCollectionElement( compositionElementDefinition );
|
|
||||||
|
|
||||||
visitAttributes( compositionElementDefinition );
|
|
||||||
|
|
||||||
strategy.finishingCompositeCollectionElement( compositionElementDefinition );
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -64,11 +64,16 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
cfg.addResource( "org/hibernate/test/onetoone/joined/Person.hbm.xml" );
|
cfg.addResource( "org/hibernate/test/onetoone/joined/Person.hbm.xml" );
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
// doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Person.class ) );
|
// doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Person.class ) );
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Entity.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Entity.class ) );
|
||||||
|
|
||||||
// doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Address.class ) );
|
// doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.joined.Address.class ) );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpecialOneToOne() {
|
public void testSpecialOneToOne() {
|
||||||
|
@ -77,8 +82,13 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
cfg.addResource( "org/hibernate/test/onetoone/formula/Person.hbm.xml" );
|
cfg.addResource( "org/hibernate/test/onetoone/formula/Person.hbm.xml" );
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.formula.Person.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.onetoone.formula.Person.class ) );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncapsulatedCompositeIdNoFetches1() {
|
public void testEncapsulatedCompositeIdNoFetches1() {
|
||||||
|
@ -88,9 +98,15 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.CardField.class );
|
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.CardField.class );
|
||||||
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.Card.class );
|
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.Card.class );
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.CardField.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.CardField.class ) );
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.Card.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.Card.class ) );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncapsulatedCompositeIdNoFetches2() {
|
public void testEncapsulatedCompositeIdNoFetches2() {
|
||||||
|
@ -99,8 +115,14 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
Configuration cfg = new Configuration();
|
Configuration cfg = new Configuration();
|
||||||
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.Parent.class );
|
cfg.addAnnotatedClass( EncapsulatedCompositeIdResultSetProcessorTest.Parent.class );
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.Parent.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( EncapsulatedCompositeIdResultSetProcessorTest.Parent.class ) );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncapsulatedCompositeIdWithFetches1() {
|
public void testEncapsulatedCompositeIdWithFetches1() {
|
||||||
|
@ -112,6 +134,7 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
final OuterJoinLoadable cardFieldPersister = (OuterJoinLoadable) sf.getClassMetadata( CardField.class );
|
final OuterJoinLoadable cardFieldPersister = (OuterJoinLoadable) sf.getClassMetadata( CardField.class );
|
||||||
doCompare( sf, cardFieldPersister );
|
doCompare( sf, cardFieldPersister );
|
||||||
|
|
||||||
|
@ -155,6 +178,10 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
// a special "identifier reader". generated aliases could help here too to remove cyclic-ness from the graph.
|
// a special "identifier reader". generated aliases could help here too to remove cyclic-ness from the graph.
|
||||||
// but at any rate, we need to know still when this becomes circularity
|
// but at any rate, we need to know still when this becomes circularity
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncapsulatedCompositeIdWithFetches2() {
|
public void testEncapsulatedCompositeIdWithFetches2() {
|
||||||
|
@ -165,6 +192,8 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
cfg.addAnnotatedClass( PrimaryKey.class );
|
cfg.addAnnotatedClass( PrimaryKey.class );
|
||||||
|
|
||||||
final SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
final SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
final OuterJoinLoadable cardPersister = (OuterJoinLoadable) sf.getClassMetadata( Card.class );
|
final OuterJoinLoadable cardPersister = (OuterJoinLoadable) sf.getClassMetadata( Card.class );
|
||||||
doCompare( sf, cardPersister );
|
doCompare( sf, cardPersister );
|
||||||
|
|
||||||
|
@ -206,13 +235,23 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
|
||||||
);
|
);
|
||||||
assertEquals( Key.class.getName(), keyFetch.getEntityPersister().getEntityName() );
|
assertEquals( Key.class.getName(), keyFetch.getEntityPersister().getEntityName() );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManyToMany() {
|
public void testManyToMany() {
|
||||||
Configuration cfg = new Configuration();
|
Configuration cfg = new Configuration();
|
||||||
cfg.addResource( "org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml" );
|
cfg.addResource( "org/hibernate/test/immutable/entitywithmutablecollection/inverse/ContractVariation.hbm.xml" );
|
||||||
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
|
try {
|
||||||
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.immutable.entitywithmutablecollection.Contract.class ) );
|
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( org.hibernate.test.immutable.entitywithmutablecollection.Contract.class ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,12 @@ public class CompositesWalkingTest extends BaseUnitTestCase {
|
||||||
final SessionFactory sf = new Configuration()
|
final SessionFactory sf = new Configuration()
|
||||||
.addAnnotatedClass( TestCourse.class )
|
.addAnnotatedClass( TestCourse.class )
|
||||||
.buildSessionFactory();
|
.buildSessionFactory();
|
||||||
|
try {
|
||||||
final EntityPersister ep = (EntityPersister) sf.getClassMetadata( TestCourse.class );
|
final EntityPersister ep = (EntityPersister) sf.getClassMetadata( TestCourse.class );
|
||||||
|
|
||||||
MetamodelGraphWalker.visitEntity( new LoggingAssociationVisitationStrategy(), ep );
|
MetamodelGraphWalker.visitEntity( new LoggingAssociationVisitationStrategy(), ep );
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class LoggingAssociationVisitationStrategy implements AssociationVisitati
|
||||||
System.out.println(
|
System.out.println(
|
||||||
String.format(
|
String.format(
|
||||||
"%s Finishing composite (%s)",
|
"%s Finishing composite (%s)",
|
||||||
StringHelper.repeat( ">>", depth-- ),
|
StringHelper.repeat( "<<", depth-- ),
|
||||||
compositionDefinition.getName()
|
compositionDefinition.getName()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -206,28 +206,28 @@ public class LoggingAssociationVisitationStrategy implements AssociationVisitati
|
||||||
|
|
||||||
|
|
||||||
// why do we have these + startingCollectionElements/finishingCollectionElements ???
|
// why do we have these + startingCollectionElements/finishingCollectionElements ???
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
// public void startingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
||||||
System.out.println(
|
// System.out.println(
|
||||||
String.format(
|
// String.format(
|
||||||
"%s Starting composite (%s)",
|
// "%s Starting composite (%s)",
|
||||||
StringHelper.repeat( ">>", ++depth ),
|
// StringHelper.repeat( ">>", ++depth ),
|
||||||
compositionElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
// compositionElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
// public void finishingCompositeCollectionElement(CompositeCollectionElementDefinition compositionElementDefinition) {
|
||||||
System.out.println(
|
// System.out.println(
|
||||||
String.format(
|
// String.format(
|
||||||
"%s Finishing composite (%s)",
|
// "%s Finishing composite (%s)",
|
||||||
StringHelper.repeat( "<<", depth-- ),
|
// StringHelper.repeat( "<<", depth-- ),
|
||||||
compositionElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
// compositionElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void foundAny(AssociationAttributeDefinition attributeDefinition, AnyMappingDefinition anyDefinition) {
|
public void foundAny(AssociationAttributeDefinition attributeDefinition, AnyMappingDefinition anyDefinition) {
|
||||||
|
|
|
@ -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.test.loadplans.walking;
|
||||||
|
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.walking.spi.MetamodelGraphWalker;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.hibernate.test.loadplans.process.EncapsulatedCompositeAttributeResultSetProcessorTest.Person;
|
||||||
|
import org.hibernate.test.loadplans.process.EncapsulatedCompositeAttributeResultSetProcessorTest.Customer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class NestedCompositeElementTest extends BaseCoreFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { Person.class, Customer.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWalkingKeyManyToOneGraphs() {
|
||||||
|
final EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata( Customer.class );
|
||||||
|
MetamodelGraphWalker.visitEntity( new LoggingAssociationVisitationStrategy(), ep );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue