HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)

This commit is contained in:
Gail Badner 2013-09-23 16:11:27 -07:00 committed by Steve Ebersole
parent 4420fa71d6
commit f111600e1f
40 changed files with 504 additions and 608 deletions

View File

@ -469,6 +469,10 @@ public final class SessionFactoryImpl
);
// after *all* persisters and named queries are registered
for ( EntityPersister persister : entityPersisters.values() ) {
persister.generateEntityDefinition();
}
for ( EntityPersister persister : entityPersisters.values() ) {
persister.postInstantiate();
registerEntityNameResolvers( persister );

View File

@ -23,16 +23,11 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityIdentifierDescription;
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.loader.plan2.spi.Join;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.type.CompositeType;
/**
@ -47,7 +42,7 @@ public abstract class AbstractCompositeEntityIdentifierDescription
protected AbstractCompositeEntityIdentifierDescription(
EntityReference entityReference,
CompositeQuerySpace compositeQuerySpace,
ExpandingCompositeQuerySpace compositeQuerySpace,
CompositeType identifierType,
PropertyPath propertyPath) {
super( identifierType, compositeQuerySpace, false, propertyPath );
@ -59,6 +54,11 @@ public abstract class AbstractCompositeEntityIdentifierDescription
return getFetches().length > 0;
}
@Override
public boolean hasBidirectionalEntityReferences() {
return getBidirectionalEntityReferences().length > 0;
}
@Override
public FetchSource getSource() {
// the source for this (as a Fetch) is the entity reference

View File

@ -23,63 +23,40 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.CollectionFetch;
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.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.loader.plan2.spi.Join;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.CollectionType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/**
* @author Steve Ebersole
* @author Gail Badner
*/
public abstract class AbstractCompositeFetch implements CompositeFetch, ExpandingFetchSource {
public abstract class AbstractCompositeFetch extends AbstractExpandingFetchSource implements CompositeFetch {
private static final FetchStrategy FETCH_STRATEGY = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
private final CompositeType compositeType;
private final CompositeQuerySpace compositeQuerySpace;
private final PropertyPath propertyPath;
private final boolean allowCollectionFetches;
private List<Fetch> fetches;
protected AbstractCompositeFetch(
CompositeType compositeType,
CompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches, PropertyPath propertyPath) {
ExpandingCompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches,
PropertyPath propertyPath) {
super( compositeQuerySpace, propertyPath );
this.compositeType = compositeType;
this.compositeQuerySpace = compositeQuerySpace;
this.allowCollectionFetches = allowCollectionFetches;
this.propertyPath = propertyPath;
}
@SuppressWarnings("UnusedParameters")
protected CompositeQuerySpace resolveCompositeQuerySpace(LoadPlanBuildingContext loadPlanBuildingContext) {
return compositeQuerySpace;
}
@Override
@ -106,101 +83,21 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
);
}
@Override
public String getQuerySpaceUid() {
return compositeQuerySpace.getUid();
}
@Override
public void validateFetchPlan(FetchStrategy fetchStrategy, AttributeDefinition attributeDefinition) {
// anything to do here?
}
@Override
public EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
return buildEntityFetch( attributeDefinition, fetchStrategy, null, loadPlanBuildingContext );
}
@Override
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference entityReference,
LoadPlanBuildingContext loadPlanBuildingContext) {
return (BidirectionalEntityFetch) buildEntityFetch(
attributeDefinition, fetchStrategy, entityReference, loadPlanBuildingContext
);
}
private EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference,
LoadPlanBuildingContext loadPlanBuildingContext) {
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
fetchedType.getAssociatedEntityName()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate EntityPersister [%s] for fetch [%s]",
fetchedType.getAssociatedEntityName(),
attributeDefinition.getName()
)
);
}
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) resolveCompositeQuerySpace(
loadPlanBuildingContext
);
final EntityFetch fetch;
if ( targetEntityReference == null ) {
final Join join = leftHandSide.addEntityJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid(),
attributeDefinition.isNullable()
);
fetch = new EntityFetchImpl( this, attributeDefinition, fetchStrategy, join );
}
else {
fetch = new BidirectionalEntityFetchImpl( this, attributeDefinition, fetchStrategy, targetEntityReference );
}
addFetch( fetch );
return fetch;
}
private void addFetch(Fetch fetch) {
if ( fetches == null ) {
fetches = new ArrayList<Fetch>();
}
fetches.add( fetch );
}
@Override
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition,
LoadPlanBuildingContext loadPlanBuildingContext) {
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) resolveCompositeQuerySpace( loadPlanBuildingContext );
final Join join = leftHandSide.addCompositeJoin(
attributeDefinition,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final NestedCompositeFetchImpl fetch = new NestedCompositeFetchImpl(
protected CompositeFetch createCompositeFetch(
CompositeType compositeType,
ExpandingCompositeQuerySpace compositeQuerySpace) {
return new NestedCompositeFetchImpl(
this,
attributeDefinition.getType(),
(CompositeQuerySpace) join.getRightHandSide(),
compositeType,
compositeQuerySpace,
allowCollectionFetches,
getPropertyPath()
);
addFetch( fetch );
return fetch;
}
@Override
@ -212,50 +109,11 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
throw new WalkingException(
String.format(
"This composite path [%s] does not allow collection fetches (composite id or composite collection index/element",
propertyPath.getFullPath()
getPropertyPath().getFullPath()
)
);
}
// 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?
final CollectionType fetchedType = (CollectionType) attributeDefinition.getType();
final CollectionPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getCollectionPersister(
fetchedType.getRole()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate CollectionPersister [%s] for fetch [%s]",
fetchedType.getRole(),
attributeDefinition.getName()
)
);
}
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) loadPlanBuildingContext.getQuerySpaces().getQuerySpaceByUid(
getQuerySpaceUid()
);
final Join join = leftHandSide.addCollectionJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final CollectionFetch fetch = new CollectionFetchImpl(
this,
attributeDefinition,
fetchStrategy,
join,
loadPlanBuildingContext
);
addFetch( fetch );
return fetch;
}
@Override
public PropertyPath getPropertyPath() {
return propertyPath;
return super.buildCollectionFetch( attributeDefinition, fetchStrategy, loadPlanBuildingContext );
}
@Override
@ -278,12 +136,6 @@ public abstract class AbstractCompositeFetch implements CompositeFetch, Expandin
return null;
}
@Override
public Fetch[] getFetches() {
return (fetches == null) ? NO_FETCHES : fetches.toArray( new Fetch[fetches.size()] );
}
// this is being removed to be more ogm/search friendly
@Override
public String[] toSqlSelectFragments(String alias) {

View File

@ -23,56 +23,36 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.CollectionFetch;
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.EntityIdentifierDescription;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.loader.plan2.spi.Join;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.EncapsulatedEntityIdentifierDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.CollectionType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/**
* @author Steve Ebersole
*/
public abstract class AbstractEntityReference implements EntityReference, ExpandingFetchSource {
private final EntityQuerySpace entityQuerySpace;
private final PropertyPath propertyPath;
public abstract class AbstractEntityReference extends AbstractExpandingFetchSource implements EntityReference {
private final EntityIdentifierDescription identifierDescription;
private List<Fetch> fetches;
public AbstractEntityReference(
EntityQuerySpace entityQuerySpace,
ExpandingEntityQuerySpace entityQuerySpace,
PropertyPath propertyPath) {
this.entityQuerySpace = entityQuerySpace;
this.propertyPath = propertyPath;
super( entityQuerySpace, propertyPath );
this.identifierDescription = buildIdentifierDescription();
}
private ExpandingEntityQuerySpace expandingEntityQuerySpace() {
return (ExpandingEntityQuerySpace) expandingQuerySpace();
}
/**
* Builds just the first level of identifier description. This will be either a simple id descriptor (String,
@ -81,8 +61,7 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
* @return the descriptor for the identifier
*/
private EntityIdentifierDescription buildIdentifierDescription() {
final EntityPersister persister = entityQuerySpace.getEntityPersister();
final EntityIdentifierDefinition identifierDefinition = persister.getEntityKeyDefinition();
final EntityIdentifierDefinition identifierDefinition = getEntityPersister().getEntityKeyDefinition();
if ( identifierDefinition.isEncapsulated() ) {
final EncapsulatedEntityIdentifierDefinition encapsulatedIdentifierDefinition = (EncapsulatedEntityIdentifierDefinition) identifierDefinition;
@ -93,7 +72,7 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
}
// if we get here, we know we have a composite identifier...
final Join join = ( (ExpandingEntityQuerySpace) entityQuerySpace ).makeCompositeIdentifierJoin();
final Join join = expandingEntityQuerySpace().makeCompositeIdentifierJoin();
return identifierDefinition.isEncapsulated()
? buildEncapsulatedCompositeIdentifierDescription( join )
: buildNonEncapsulatedCompositeIdentifierDescription( join );
@ -102,18 +81,18 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
private NonEncapsulatedEntityIdentifierDescription buildNonEncapsulatedCompositeIdentifierDescription(Join compositeJoin) {
return new NonEncapsulatedEntityIdentifierDescription(
this,
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
(CompositeType) entityQuerySpace.getEntityPersister().getIdentifierType(),
propertyPath.append( "id" )
(ExpandingCompositeQuerySpace) compositeJoin.getRightHandSide(),
(CompositeType) getEntityPersister().getIdentifierType(),
getPropertyPath().append( "id" )
);
}
private EncapsulatedEntityIdentifierDescription buildEncapsulatedCompositeIdentifierDescription(Join compositeJoin) {
return new EncapsulatedEntityIdentifierDescription(
this,
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
(CompositeType) entityQuerySpace.getEntityPersister().getIdentifierType(),
propertyPath.append( "id" )
(ExpandingCompositeQuerySpace) compositeJoin.getRightHandSide(),
(CompositeType) getEntityPersister().getIdentifierType(),
getPropertyPath().append( "id" )
);
}
@ -122,18 +101,9 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
return this;
}
protected EntityQuerySpace getEntityQuerySpace() {
return entityQuerySpace;
}
@Override
public String getQuerySpaceUid() {
return getEntityQuerySpace().getUid();
}
@Override
public EntityPersister getEntityPersister() {
return entityQuerySpace.getEntityPersister();
return expandingEntityQuerySpace().getEntityPersister();
}
@Override
@ -141,141 +111,15 @@ public abstract class AbstractEntityReference implements EntityReference, Expand
return identifierDescription;
}
@Override
public PropertyPath getPropertyPath() {
return propertyPath;
}
@Override
public Fetch[] getFetches() {
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
}
@Override
public EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
return buildEntityFetch( attributeDefinition, fetchStrategy, null, loadPlanBuildingContext );
}
@Override
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference,
LoadPlanBuildingContext loadPlanBuildingContext) {
return (BidirectionalEntityFetch) buildEntityFetch(
attributeDefinition, fetchStrategy, targetEntityReference, loadPlanBuildingContext
);
}
private EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference,
LoadPlanBuildingContext loadPlanBuildingContext) {
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
fetchedType.getAssociatedEntityName()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate EntityPersister [%s] for fetch [%s]",
fetchedType.getAssociatedEntityName(),
attributeDefinition.getName()
)
);
}
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) entityQuerySpace;
final EntityFetch fetch;
if ( targetEntityReference == null ) {
final Join join = leftHandSide.addEntityJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid(),
attributeDefinition.isNullable()
);
fetch = new EntityFetchImpl( this, attributeDefinition, fetchStrategy, join );
}
else {
fetch = new BidirectionalEntityFetchImpl( this, attributeDefinition, fetchStrategy, targetEntityReference );
}
addFetch( fetch );
return fetch;
}
private void addFetch(Fetch fetch) {
if ( fetches == null ) {
fetches = new ArrayList<Fetch>();
}
fetches.add( fetch );
}
@Override
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition,
LoadPlanBuildingContext loadPlanBuildingContext) {
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) entityQuerySpace;
final Join join = leftHandSide.addCompositeJoin(
attributeDefinition,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final CompositeFetchImpl fetch = new CompositeFetchImpl(
protected CompositeFetch createCompositeFetch(
CompositeType compositeType,
ExpandingCompositeQuerySpace compositeQuerySpace) {
return new CompositeFetchImpl(
this,
attributeDefinition.getType(),
(CompositeQuerySpace) join.getRightHandSide(),
compositeType,
compositeQuerySpace,
true,
getPropertyPath()
);
addFetch( fetch );
return fetch;
}
@Override
public CollectionFetch buildCollectionFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
// 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?
final CollectionType fetchedType = (CollectionType) attributeDefinition.getType();
final CollectionPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getCollectionPersister(
fetchedType.getRole()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate CollectionPersister [%s] for fetch [%s]",
fetchedType.getRole(),
attributeDefinition.getName()
)
);
}
final ExpandingQuerySpace leftHandSide = (ExpandingQuerySpace) loadPlanBuildingContext.getQuerySpaces().getQuerySpaceByUid(
getQuerySpaceUid()
);
final Join join = leftHandSide.addCollectionJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final CollectionFetch fetch = new CollectionFetchImpl(
this,
attributeDefinition,
fetchStrategy,
join,
loadPlanBuildingContext
);
addFetch( fetch );
return fetch;
}
}

View File

@ -0,0 +1,236 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan2.build.internal.returns;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.loader.plan2.spi.CollectionFetch;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.loader.plan2.spi.Join;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.type.CollectionType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
/**
* @author Gail Badner
*/
public abstract class AbstractExpandingFetchSource implements ExpandingFetchSource {
/**
* Convenient constant for returning no fetches from {@link #getFetches()}
*/
private static final Fetch[] NO_FETCHES = new Fetch[0];
/**
* Convenient constant for returning no fetches from {@link #getFetches()}
*/
private static final BidirectionalEntityReference[] NO_BIDIRECTIONAL_ENTITY_REFERENCES =
new BidirectionalEntityReference[0];
private final ExpandingQuerySpace querySpace;
private final PropertyPath propertyPath;
private List<Fetch> fetches;
private List<BidirectionalEntityReference> bidirectionalEntityReferences;
public AbstractExpandingFetchSource(ExpandingQuerySpace querySpace, PropertyPath propertyPath) {
this.querySpace = querySpace;
this.propertyPath = propertyPath;
}
@Override
public final String getQuerySpaceUid() {
return querySpace.getUid();
}
protected final ExpandingQuerySpace expandingQuerySpace() {
return querySpace;
}
@Override
public final PropertyPath getPropertyPath() {
return propertyPath;
}
@Override
public Fetch[] getFetches() {
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
}
private void addFetch(Fetch fetch) {
if ( fetches == null ) {
fetches = new ArrayList<Fetch>();
}
fetches.add( fetch );
}
@Override
public BidirectionalEntityReference[] getBidirectionalEntityReferences() {
return bidirectionalEntityReferences == null ?
NO_BIDIRECTIONAL_ENTITY_REFERENCES :
bidirectionalEntityReferences.toArray(
new BidirectionalEntityReference[ bidirectionalEntityReferences.size() ]
);
}
private void addBidirectionalEntityReference(BidirectionalEntityReference bidirectionalEntityReference) {
if ( bidirectionalEntityReferences == null ) {
bidirectionalEntityReferences = new ArrayList<BidirectionalEntityReference>();
}
bidirectionalEntityReferences.add( bidirectionalEntityReference );
}
@Override
public EntityFetch buildEntityFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
fetchedType.getAssociatedEntityName()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate EntityPersister [%s] for fetch [%s]",
fetchedType.getAssociatedEntityName(),
attributeDefinition.getName()
)
);
}
final Join join = querySpace.addEntityJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid(),
attributeDefinition.isNullable()
);
final EntityFetch fetch = new EntityFetchImpl( this, attributeDefinition, fetchStrategy, join );
addFetch( fetch );
return fetch;
}
@Override
public BidirectionalEntityReference buildBidirectionalEntityReference(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference,
LoadPlanBuildingContext loadPlanBuildingContext) {
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
fetchedType.getAssociatedEntityName()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate EntityPersister [%s] for bidirectional entity reference [%s]",
fetchedType.getAssociatedEntityName(),
attributeDefinition.getName()
)
);
}
final BidirectionalEntityReference bidirectionalEntityReference =
new BidirectionalEntityReferenceImpl( this, attributeDefinition, targetEntityReference );
addBidirectionalEntityReference( bidirectionalEntityReference );
return bidirectionalEntityReference;
}
protected abstract CompositeFetch createCompositeFetch(
CompositeType compositeType,
ExpandingCompositeQuerySpace compositeQuerySpace);
@Override
public CompositeFetch buildCompositeFetch(
CompositionDefinition attributeDefinition,
LoadPlanBuildingContext loadPlanBuildingContext) {
final ExpandingQuerySpace leftHandSide = expandingQuerySpace();
final Join join = leftHandSide.addCompositeJoin(
attributeDefinition,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final CompositeFetch fetch = createCompositeFetch(
attributeDefinition.getType(),
(ExpandingCompositeQuerySpace) join.getRightHandSide()
);
addFetch( fetch );
return fetch;
}
@Override
public CollectionFetch buildCollectionFetch(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext) {
// 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?
final CollectionType fetchedType = (CollectionType) attributeDefinition.getType();
final CollectionPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getCollectionPersister(
fetchedType.getRole()
);
if ( fetchedPersister == null ) {
throw new WalkingException(
String.format(
"Unable to locate CollectionPersister [%s] for fetch [%s]",
fetchedType.getRole(),
attributeDefinition.getName()
)
);
}
final Join join = querySpace.addCollectionJoin(
attributeDefinition,
fetchedPersister,
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid()
);
final CollectionFetch fetch = new CollectionFetchImpl(
this,
attributeDefinition,
fetchStrategy,
join,
loadPlanBuildingContext
);
addFetch( fetch );
return fetch;
}
}

View File

@ -23,18 +23,15 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.loader.plan2.spi.EntityIdentifierDescription;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.loader.plan2.spi.Fetch;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.type.EntityType;
/**
* Represents an entity fetch that is bi-directionally join fetched.
@ -45,21 +42,14 @@ import org.hibernate.type.EntityType;
*
* @author Steve Ebersole
*/
public class BidirectionalEntityFetchImpl implements BidirectionalEntityFetch, EntityFetch {
private final ExpandingFetchSource fetchSource;
private final AssociationAttributeDefinition fetchedAttribute;
private final FetchStrategy fetchStrategy;
public class BidirectionalEntityReferenceImpl implements BidirectionalEntityReference {
private final EntityReference targetEntityReference;
private final PropertyPath propertyPath;
public BidirectionalEntityFetchImpl(
public BidirectionalEntityReferenceImpl(
ExpandingFetchSource fetchSource,
AssociationAttributeDefinition fetchedAttribute,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference) {
this.fetchSource = fetchSource;
this.fetchedAttribute = fetchedAttribute;
this.fetchStrategy = fetchStrategy;
this.targetEntityReference = targetEntityReference;
this.propertyPath = fetchSource.getPropertyPath().append( fetchedAttribute.getName() );
}
@ -68,41 +58,11 @@ public class BidirectionalEntityFetchImpl implements BidirectionalEntityFetch, E
return targetEntityReference;
}
@Override
public FetchSource getSource() {
return fetchSource;
}
@Override
public PropertyPath getPropertyPath() {
return propertyPath;
}
@Override
public FetchStrategy getFetchStrategy() {
return fetchStrategy;
}
@Override
public EntityType getFetchedType() {
return (EntityType) fetchedAttribute.getType();
}
@Override
public boolean isNullable() {
return fetchedAttribute.isNullable();
}
@Override
public String getAdditionalJoinConditions() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String[] toSqlSelectFragments(String alias) {
return new String[0]; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getQuerySpaceUid() {
return targetEntityReference.getQuerySpaceUid();
@ -110,7 +70,12 @@ public class BidirectionalEntityFetchImpl implements BidirectionalEntityFetch, E
@Override
public Fetch[] getFetches() {
return FetchSource.NO_FETCHES;
return targetEntityReference.getFetches();
}
@Override
public BidirectionalEntityReference[] getBidirectionalEntityReferences() {
return targetEntityReference.getBidirectionalEntityReferences();
}
@Override

View File

@ -23,10 +23,10 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
import org.hibernate.loader.plan2.spi.CollectionReference;
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.Join;
import org.hibernate.type.CompositeType;
@ -45,7 +45,7 @@ public class CollectionFetchableElementCompositeGraph
public CollectionFetchableElementCompositeGraph(CollectionReference collectionReference, Join compositeJoin) {
super(
(CompositeType) compositeJoin.getRightHandSide().getPropertyMapping().getType(),
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
(ExpandingCompositeQuerySpace) compositeJoin.getRightHandSide(),
false,
// these property paths are just informational...
collectionReference.getPropertyPath().append( "<element>" )

View File

@ -24,6 +24,7 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
import org.hibernate.loader.plan2.spi.CollectionReference;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
@ -41,7 +42,7 @@ public class CollectionFetchableElementEntityGraph extends AbstractEntityReferen
CollectionReference collectionReference,
Join entityJoin) {
super(
(EntityQuerySpace) entityJoin.getRightHandSide(),
(ExpandingEntityQuerySpace) entityJoin.getRightHandSide(),
collectionReference.getPropertyPath().append( "<elements>" )
);
@ -49,11 +50,6 @@ public class CollectionFetchableElementEntityGraph extends AbstractEntityReferen
this.entityQuerySpace = (EntityQuerySpace) entityJoin.getRightHandSide();
}
@Override
protected EntityQuerySpace getEntityQuerySpace() {
return entityQuerySpace;
}
@Override
public CollectionReference getCollectionReference() {
return collectionReference;

View File

@ -23,10 +23,10 @@
*/
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
import org.hibernate.loader.plan2.spi.CollectionReference;
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.Join;
import org.hibernate.type.CompositeType;
@ -49,7 +49,7 @@ public class CollectionFetchableIndexCompositeGraph
Join compositeJoin) {
super(
extractIndexType( compositeJoin ),
(CompositeQuerySpace) compositeJoin.getRightHandSide(),
(ExpandingCompositeQuerySpace) compositeJoin.getRightHandSide(),
false,
collectionReference.getPropertyPath().append( "<index>" )
);

View File

@ -24,6 +24,7 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
import org.hibernate.loader.plan2.spi.CollectionReference;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
@ -41,7 +42,7 @@ public class CollectionFetchableIndexEntityGraph extends AbstractEntityReference
CollectionReference collectionReference,
Join entityJoin) {
super(
(EntityQuerySpace) entityJoin.getRightHandSide(),
(ExpandingEntityQuerySpace) entityJoin.getRightHandSide(),
collectionReference.getPropertyPath().append( "<index>" )
);
@ -54,11 +55,6 @@ public class CollectionFetchableIndexEntityGraph extends AbstractEntityReference
return collectionReference;
}
@Override
protected EntityQuerySpace getEntityQuerySpace() {
return entityQuerySpace;
}
@Override
public void validateFetchPlan(FetchStrategy fetchStrategy, AttributeDefinition attributeDefinition) {
}

View File

@ -24,8 +24,8 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.type.CompositeType;
@ -38,7 +38,7 @@ public class CompositeFetchImpl extends AbstractCompositeFetch implements Compos
protected CompositeFetchImpl(
FetchSource source,
CompositeType compositeType,
CompositeQuerySpace compositeQuerySpace,
ExpandingCompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches,
PropertyPath propertyPath) {
super( compositeType, compositeQuerySpace, allowCollectionFetches, propertyPath );

View File

@ -24,6 +24,7 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityIdentifierDescription;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.spi.EntityReference;
@ -49,7 +50,7 @@ public class EncapsulatedEntityIdentifierDescription
*/
protected EncapsulatedEntityIdentifierDescription(
EntityReference entityReference,
CompositeQuerySpace compositeQuerySpace,
ExpandingCompositeQuerySpace compositeQuerySpace,
CompositeType compositeType,
PropertyPath propertyPath) {
super( entityReference, compositeQuerySpace, compositeType, propertyPath );

View File

@ -24,14 +24,13 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.FetchSource;
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.EntityType;
/**
@ -48,7 +47,7 @@ public class EntityFetchImpl extends AbstractEntityReference implements EntityFe
FetchStrategy fetchStrategy,
Join fetchedJoin) {
super(
(EntityQuerySpace) fetchedJoin.getRightHandSide(),
(ExpandingEntityQuerySpace) fetchedJoin.getRightHandSide(),
fetchSource.getPropertyPath().append( fetchedAttribute.getName() )
);

View File

@ -24,8 +24,8 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.spi.FetchSource;
import org.hibernate.type.CompositeType;
@ -38,7 +38,7 @@ public class NestedCompositeFetchImpl extends AbstractCompositeFetch {
public NestedCompositeFetchImpl(
CompositeFetch source,
CompositeType type,
CompositeQuerySpace compositeQuerySpace,
ExpandingCompositeQuerySpace compositeQuerySpace,
boolean allowCollectionFetches, PropertyPath propertyPath) {
super( type, compositeQuerySpace, allowCollectionFetches, propertyPath );
this.source = source;

View File

@ -24,7 +24,7 @@
package org.hibernate.loader.plan2.build.internal.returns;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan2.spi.EntityReference;
import org.hibernate.type.CompositeType;
@ -45,7 +45,7 @@ public class NonEncapsulatedEntityIdentifierDescription extends AbstractComposit
*/
public NonEncapsulatedEntityIdentifierDescription(
EntityReference entityReference,
CompositeQuerySpace compositeQuerySpace,
ExpandingCompositeQuerySpace compositeQuerySpace,
CompositeType compositeType,
PropertyPath propertyPath) {
super(

View File

@ -33,4 +33,9 @@ public class SimpleEntityIdentifierDescriptionImpl implements EntityIdentifierDe
public boolean hasFetches() {
return false;
}
@Override
public boolean hasBidirectionalEntityReferences() {
return false;
}
}

View File

@ -25,8 +25,7 @@ package org.hibernate.loader.plan2.build.internal.spaces;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.plan2.build.spi.AbstractQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.PropertyMapping;
@ -40,7 +39,7 @@ import org.hibernate.type.EntityType;
/**
* @author Steve Ebersole
*/
public class CompositeQuerySpaceImpl extends AbstractQuerySpace implements CompositeQuerySpace, ExpandingQuerySpace {
public class CompositeQuerySpaceImpl extends AbstractQuerySpace implements ExpandingCompositeQuerySpace {
private final CompositePropertyMapping compositeSubPropertyMapping;
public CompositeQuerySpaceImpl(

View File

@ -26,13 +26,11 @@ package org.hibernate.loader.plan2.build.internal.spaces;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.plan2.build.spi.AbstractQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.Join;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.type.AssociationType;
@ -43,7 +41,7 @@ import org.hibernate.type.EntityType;
/**
* @author Steve Ebersole
*/
public class EntityQuerySpaceImpl extends AbstractQuerySpace implements ExpandingEntityQuerySpace, EntityQuerySpace {
public class EntityQuerySpaceImpl extends AbstractQuerySpace implements ExpandingEntityQuerySpace {
private final EntityPersister persister;
public EntityQuerySpaceImpl(

View File

@ -32,9 +32,9 @@ import org.jboss.logging.Logger;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.loader.plan2.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpaces;
import org.hibernate.loader.plan2.spi.CollectionQuerySpace;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.QuerySpace;
import org.hibernate.loader.plan2.spi.QuerySpaceUidNotRegisteredException;
import org.hibernate.persister.collection.CollectionPersister;
@ -86,7 +86,7 @@ public class QuerySpacesImpl implements ExpandingQuerySpaces {
}
@Override
public EntityQuerySpace makeEntityQuerySpace(String uid, EntityPersister entityPersister) {
public ExpandingEntityQuerySpace makeEntityQuerySpace(String uid, EntityPersister entityPersister) {
if ( querySpaceByUid.containsKey( uid ) ) {
throw new IllegalStateException( "Encountered duplicate QuerySpace uid : " + uid );
}

View File

@ -599,7 +599,7 @@ public abstract class AbstractLoadPlanBuildingAssociationVisitationStrategy
// it must be loaded when the ID for the dependent entity is resolved. Is there some other way to
// deal with this???
if ( ! associationKey.equals( currentEntityReferenceAssociationKey ) ) {
currentSource().buildBidirectionalEntityFetch(
currentSource().buildBidirectionalEntityReference(
attributeDefinition,
fetchStrategy,
registeredFetchSource( associationKey ).resolveEntityReference(),

View File

@ -0,0 +1,32 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.loader.plan2.build.spi;
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
/**
* @author Gail Badner
*/
public interface ExpandingCompositeQuerySpace extends CompositeQuerySpace, ExpandingQuerySpace {
}

View File

@ -23,11 +23,12 @@
*/
package org.hibernate.loader.plan2.build.spi;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.Join;
/**
* @author Steve Ebersole
*/
public interface ExpandingEntityQuerySpace extends ExpandingQuerySpace {
public interface ExpandingEntityQuerySpace extends EntityQuerySpace, ExpandingQuerySpace {
public Join makeCompositeIdentifierJoin();
}

View File

@ -24,7 +24,7 @@
package org.hibernate.loader.plan2.build.spi;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.loader.plan2.spi.CollectionFetch;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.EntityFetch;
@ -54,7 +54,7 @@ public interface ExpandingFetchSource extends FetchSource {
FetchStrategy fetchStrategy,
LoadPlanBuildingContext loadPlanBuildingContext);
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
public BidirectionalEntityReference buildBidirectionalEntityReference(
AssociationAttributeDefinition attributeDefinition,
FetchStrategy fetchStrategy,
EntityReference targetEntityReference,

View File

@ -24,7 +24,6 @@
package org.hibernate.loader.plan2.build.spi;
import org.hibernate.loader.plan2.spi.CollectionQuerySpace;
import org.hibernate.loader.plan2.spi.EntityQuerySpace;
import org.hibernate.loader.plan2.spi.QuerySpaces;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -35,7 +34,7 @@ import org.hibernate.persister.entity.EntityPersister;
public interface ExpandingQuerySpaces extends QuerySpaces {
public String generateImplicitUid();
public EntityQuerySpace makeEntityQuerySpace(String uid, EntityPersister entityPersister);
public ExpandingEntityQuerySpace makeEntityQuerySpace(String uid, EntityPersister entityPersister);
public CollectionQuerySpace makeCollectionQuerySpace(String uid, CollectionPersister collectionPersister);
}

View File

@ -27,7 +27,7 @@ import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.loader.plan2.spi.CollectionFetch;
import org.hibernate.loader.plan2.spi.CollectionFetchableElement;
import org.hibernate.loader.plan2.spi.CollectionFetchableIndex;
@ -153,7 +153,7 @@ public class ReturnGraphTreePrinter {
}
private void writeEntityReferenceFetches(EntityReference entityReference, int depth, PrintWriter printWriter) {
if ( BidirectionalEntityFetch.class.isInstance( entityReference ) ) {
if ( BidirectionalEntityReference.class.isInstance( entityReference ) ) {
return;
}
if ( entityReference.getIdentifierDescription().hasFetches() ) {

View File

@ -39,7 +39,7 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.plan2.exec.process.internal.HydratedEntityRegistration;
import org.hibernate.loader.plan2.exec.process.internal.ResultSetProcessingContextImpl;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.loader.plan2.spi.CompositeFetch;
import org.hibernate.loader.plan2.spi.EntityFetch;
import org.hibernate.loader.plan2.spi.EntityIdentifierDescription;
@ -129,7 +129,7 @@ public abstract class AbstractRowReader implements RowReader {
final EntityReference entityReference = entityReferenceInitializer.getEntityReference();
final EntityIdentifierDescription identifierDescription = entityReference.getIdentifierDescription();
if ( identifierDescription.hasFetches() ) {
if ( identifierDescription.hasFetches() || identifierDescription.hasBidirectionalEntityReferences() ) {
resolveEntityKey( resultSet, context, (FetchSource) identifierDescription, initializerByEntityReference );
}
entityReferenceInitializer.resolveEntityKey( resultSet, context );
@ -140,20 +140,11 @@ public abstract class AbstractRowReader implements RowReader {
ResultSetProcessingContextImpl context,
FetchSource fetchSource,
Map<EntityReference,EntityReferenceInitializer> initializerByEntityReference) throws SQLException {
for ( Fetch fetch : fetchSource.getFetches() ) {
if ( EntityFetch.class.isInstance( fetch ) ) {
final EntityFetch entityFetch = (EntityFetch) fetch;
final EntityReferenceInitializer targetEntityReferenceInitializer;
if ( BidirectionalEntityFetch.class.isInstance( fetch ) ) {
final BidirectionalEntityFetch bidirectionalEntityFetch = (BidirectionalEntityFetch) fetch;
targetEntityReferenceInitializer = initializerByEntityReference.get(
bidirectionalEntityFetch.getTargetEntityReference()
// Resolve any bidirectional entity references first.
for ( BidirectionalEntityReference bidirectionalEntityReference : fetchSource.getBidirectionalEntityReferences() ) {
final EntityReferenceInitializer targetEntityReferenceInitializer = initializerByEntityReference.get(
bidirectionalEntityReference.getTargetEntityReference()
);
}
else {
targetEntityReferenceInitializer = initializerByEntityReference.get( entityFetch );
}
if ( targetEntityReferenceInitializer != null ) {
resolveEntityKey(
resultSet,
context,
@ -162,6 +153,19 @@ public abstract class AbstractRowReader implements RowReader {
);
targetEntityReferenceInitializer.hydrateEntityState( resultSet, context );
}
for ( Fetch fetch : fetchSource.getFetches() ) {
if ( EntityFetch.class.isInstance( fetch ) ) {
final EntityFetch entityFetch = (EntityFetch) fetch;
final EntityReferenceInitializer entityReferenceInitializer = initializerByEntityReference.get( entityFetch );
if ( entityReferenceInitializer != null ) {
resolveEntityKey(
resultSet,
context,
entityReferenceInitializer,
initializerByEntityReference
);
entityReferenceInitializer.hydrateEntityState( resultSet, context );
}
}
else if ( CompositeFetch.class.isInstance( fetch ) ) {
resolveEntityKey(

View File

@ -38,7 +38,7 @@ package org.hibernate.loader.plan2.spi;
*
* @author Steve Ebersole
*/
public interface BidirectionalEntityFetch {
public interface BidirectionalEntityReference extends EntityReference {
/**
* Get the targeted EntityReference
*

View File

@ -37,4 +37,13 @@ public interface EntityIdentifierDescription {
* non-empty results for {@link FetchSource#getFetches()}
*/
public boolean hasFetches();
/**
* Can this EntityIdentifierDescription be treated as a FetchSource and if so does it have any
* bidirectional entity references?
*
* @return {@code true} iff {@code this} can be cast to {@link FetchSource} and (after casting) it returns
* non-empty results for {@link FetchSource#getBidirectionalEntityReferences()}
*/
public boolean hasBidirectionalEntityReferences();
}

View File

@ -32,10 +32,6 @@ import org.hibernate.loader.PropertyPath;
* @author Steve Ebersole
*/
public interface FetchSource {
/**
* Convenient constant for returning no fetches from {@link #getFetches()}
*/
public static final Fetch[] NO_FETCHES = new Fetch[0];
/**
* Get the property path to this fetch owner
@ -47,12 +43,19 @@ public interface FetchSource {
public String getQuerySpaceUid();
/**
* Retrieve the fetches owned by this return.
* Retrieve the fetches owned by this fetch source.
*
* @return The owned fetches.
*/
public Fetch[] getFetches();
/**
* Retrieve the bidirectional entity references owned by this fetch source.
*
* @return The owned bidirectional entity references.
*/
public BidirectionalEntityReference[] getBidirectionalEntityReferences();
/**
* Resolve the "current" {@link EntityReference}, or null if none.
*

View File

@ -3792,8 +3792,6 @@ public abstract class AbstractEntityPersister
}
private void doLateInit() {
generateEntityDefinition();
//insert/update/delete SQL
final int joinSpan = getTableSpan();
sqlDeleteStrings = new String[joinSpan];
@ -3854,7 +3852,6 @@ public abstract class AbstractEntityPersister
public final void postInstantiate() throws MappingException {
doLateInit();
// generateEntityDefinition();
createLoaders();
createUniqueKeyLoaders();
@ -5120,7 +5117,8 @@ public abstract class AbstractEntityPersister
private Iterable<AttributeDefinition> embeddedCompositeIdentifierAttributes;
private Iterable<AttributeDefinition> attributeDefinitions;
protected void generateEntityDefinition() {
@Override
public void generateEntityDefinition() {
prepareEntityIdentifierDefinition();
collectAttributeDefinitions();
}

View File

@ -45,7 +45,6 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.sql.ordering.antlr.ColumnMapper;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.Type;
@ -71,7 +70,14 @@ public interface EntityPersister extends OptimisticCacheSource, EntityDefinition
public static final String ENTITY_ID = "id";
/**
* Finish the initialization of this object.
* Generate the entity definition for this object. This must be done for all
* entity persisters before calling {@link #postInstantiate()}.
*/
public void generateEntityDefinition();
/**
* Finish the initialization of this object. {@link #generateEntityDefinition()}
* must be called for all entity persisters before calling this method.
* <p/>
* Called only once per {@link org.hibernate.SessionFactory} lifecycle,
* after all entity persisters have been instantiated.

View File

@ -1,63 +0,0 @@
/*
* 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.tuple.component;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
import org.hibernate.tuple.BaselineAttributeInformation;
import org.hibernate.tuple.NonIdentifierAttribute;
import org.hibernate.type.Type;
/**
* A base class for a sub-attribute of a composite, non-identifier attribute.
*
* @author Steve Ebersole
*/
public abstract class AbstractCompositeBasedAttribute
extends AbstractNonIdentifierAttribute
implements NonIdentifierAttribute {
private final int ownerAttributeNumber;
public AbstractCompositeBasedAttribute(
AbstractCompositionAttribute source,
SessionFactoryImplementor sessionFactory,
int attributeNumber,
String attributeName,
Type attributeType,
BaselineAttributeInformation baselineInfo,
int ownerAttributeNumber) {
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
this.ownerAttributeNumber = ownerAttributeNumber;
}
protected int ownerAttributeNumber() {
return ownerAttributeNumber;
}
@Override
public AbstractCompositionAttribute getSource() {
return (AbstractCompositionAttribute) super.getSource();
}
}

View File

@ -35,7 +35,6 @@ import org.hibernate.persister.walking.spi.AssociationKey;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.AttributeSource;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
import org.hibernate.tuple.BaselineAttributeInformation;
import org.hibernate.type.AssociationType;
@ -54,14 +53,18 @@ import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
*/
public abstract class AbstractCompositionAttribute extends AbstractNonIdentifierAttribute implements
CompositionDefinition {
private final int columnStartPosition;
protected AbstractCompositionAttribute(
AttributeSource source,
SessionFactoryImplementor sessionFactory,
int attributeNumber,
int entityBasedAttributeNumber,
String attributeName,
CompositeType attributeType,
int columnStartPosition,
BaselineAttributeInformation baselineInfo) {
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
super( source, sessionFactory, entityBasedAttributeNumber, attributeName, attributeType, baselineInfo );
this.columnStartPosition = columnStartPosition;
}
@Override
@ -77,7 +80,7 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
return new Iterator<AttributeDefinition>() {
private final int numberOfAttributes = getType().getSubtypes().length;
private int currentSubAttributeNumber = 0;
private int currentColumnPosition = 0;
private int currentColumnPosition = columnStartPosition;
@Override
public boolean hasNext() {
@ -106,13 +109,13 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
JoinHelper.getLHSTableName(
aType,
attributeNumber(),
(OuterJoinLoadable) getSource()
(OuterJoinLoadable) locateOwningPersister()
),
JoinHelper.getLHSColumnNames(
aType,
attributeNumber(),
0,
(OuterJoinLoadable) getSource(),
columnPosition,
(OuterJoinLoadable) locateOwningPersister(),
sessionFactory()
)
);
@ -129,24 +132,15 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
else {
final OuterJoinLoadable entityPersister = (OuterJoinLoadable) locateOwningPersister();
lhsTableName = getLHSTableName( aType, attributeNumber(), entityPersister );
lhsColumnNames = getLHSColumnNames( aType, attributeNumber(), entityPersister, sessionFactory() );
lhsColumnNames = getLHSColumnNames(
aType,
attributeNumber(),
columnPosition,
entityPersister,
sessionFactory()
);
}
associationKey = new AssociationKey( lhsTableName, lhsColumnNames );
// associationKey = new AssociationKey(
// getLHSTableName(
// aType,
// attributeNumber(),
// (OuterJoinLoadable) locateOwningPersister()
// ),
// getLHSColumnNames(
// aType,
// attributeNumber(),
// columnPosition,
// (OuterJoinLoadable) locateOwningPersister(),
// sessionFactory()
// )
// );
}
else {
associationKey = new AssociationKey(
@ -156,12 +150,14 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
}
final CompositeType cType = getType();
final boolean nullable = cType.getPropertyNullability() == null || cType.getPropertyNullability()[subAttributeNumber];
final boolean nullable =
cType.getPropertyNullability() == null ||
cType.getPropertyNullability()[subAttributeNumber];
return new CompositeBasedAssociationAttribute(
AbstractCompositionAttribute.this,
sessionFactory(),
subAttributeNumber,
attributeNumber(),
name,
(AssociationType) type,
new BaselineAttributeInformation.Builder()
@ -175,7 +171,7 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
.createInformation(),
AbstractCompositionAttribute.this.attributeNumber(),
subAttributeNumber,
associationKey
);
}
@ -183,9 +179,10 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
return new CompositionBasedCompositionAttribute(
AbstractCompositionAttribute.this,
sessionFactory(),
subAttributeNumber,
attributeNumber(),
name,
(CompositeType) type,
columnPosition,
new BaselineAttributeInformation.Builder()
.setInsertable( AbstractCompositionAttribute.this.isInsertable() )
.setUpdateable( AbstractCompositionAttribute.this.isUpdateable() )
@ -233,14 +230,7 @@ public abstract class AbstractCompositionAttribute extends AbstractNonIdentifier
};
}
public EntityPersister locateOwningPersister() {
if ( EntityDefinition.class.isInstance( getSource() ) ) {
return ( (EntityDefinition) getSource() ).getEntityPersister();
}
else {
return ( (AbstractCompositionAttribute) getSource() ).locateOwningPersister();
}
}
protected abstract EntityPersister locateOwningPersister();
@Override
protected String loggableMetadata() {

View File

@ -43,31 +43,30 @@ import org.hibernate.persister.walking.spi.AssociationKey;
import org.hibernate.persister.walking.spi.CollectionDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.persister.walking.spi.WalkingException;
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
import org.hibernate.tuple.BaselineAttributeInformation;
import org.hibernate.tuple.NonIdentifierAttribute;
import org.hibernate.type.AnyType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.CompositeType;
/**
* @author Steve Ebersole
*/
public class CompositeBasedAssociationAttribute
extends AbstractCompositeBasedAttribute
implements AssociationAttributeDefinition {
extends AbstractNonIdentifierAttribute
implements NonIdentifierAttribute, AssociationAttributeDefinition {
private final int subAttributeNumber;
private final AssociationKey associationKey;
private Joinable joinable;
public CompositeBasedAssociationAttribute(
AbstractCompositionAttribute source,
SessionFactoryImplementor factory,
int attributeNumber,
String attributeName,
AssociationType attributeType,
BaselineAttributeInformation baselineInfo,
int ownerAttributeNumber,
int entityBasedAttributeNumber, String attributeName, AssociationType attributeType, BaselineAttributeInformation baselineInfo, int subAttributeNumber,
AssociationKey associationKey) {
super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo, ownerAttributeNumber );
super( source, factory, entityBasedAttributeNumber, attributeName, attributeType, baselineInfo );
this.subAttributeNumber = subAttributeNumber;
this.associationKey = associationKey;
}
@ -76,6 +75,11 @@ public class CompositeBasedAssociationAttribute
return (AssociationType) super.getType();
}
@Override
public AbstractCompositionAttribute getSource() {
return (AbstractCompositionAttribute) super.getSource();
}
protected Joinable getJoinable() {
if ( joinable == null ) {
joinable = getType().getAssociatedJoinable( sessionFactory() );
@ -148,37 +152,21 @@ public class CompositeBasedAssociationAttribute
@Override
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
final EntityPersister owningPersister = locateOwningPersister();
final EntityPersister owningPersister = getSource().locateOwningPersister();
FetchStyle style = determineFetchStyleByProfile(
FetchStyle style = FetchStrategyHelper.determineFetchStyleByProfile(
loadQueryInfluencers,
owningPersister,
propertyPath,
ownerAttributeNumber()
attributeNumber()
);
if ( style == null ) {
style = determineFetchStyleByMetadata(
getSource().getType().getFetchMode( attributeNumber() ),
getType()
);
style = determineFetchStyleByMetadata( getFetchMode(), getType() );
}
return new FetchStrategy( determineFetchTiming( style ), style );
}
protected FetchStyle determineFetchStyleByProfile(
LoadQueryInfluencers loadQueryInfluencers,
EntityPersister owningPersister,
PropertyPath propertyPath,
int ownerAttributeNumber) {
return FetchStrategyHelper.determineFetchStyleByProfile(
loadQueryInfluencers,
owningPersister,
propertyPath,
ownerAttributeNumber
);
}
protected FetchStyle determineFetchStyleByMetadata(FetchMode fetchMode, AssociationType type) {
return FetchStrategyHelper.determineFetchStyleByMetadata( fetchMode, type, sessionFactory() );
}
@ -187,14 +175,9 @@ public class CompositeBasedAssociationAttribute
return FetchStrategyHelper.determineFetchTiming( style, getType(), sessionFactory() );
}
private EntityPersister locateOwningPersister() {
return getSource().locateOwningPersister();
}
@Override
public CascadeStyle determineCascadeStyle() {
final CompositeType compositeType = (CompositeType) locateOwningPersister().getPropertyType( getName() );
return compositeType.getCascadeStyle( attributeNumber() );
return getCascadeStyle();
}
private HydratedCompoundValueHandler hydratedCompoundValueHandler;
@ -205,12 +188,12 @@ public class CompositeBasedAssociationAttribute
hydratedCompoundValueHandler = new HydratedCompoundValueHandler() {
@Override
public Object extract(Object hydratedState) {
return ( (Object[] ) hydratedState )[ attributeNumber() ];
return ( (Object[] ) hydratedState )[ subAttributeNumber ];
}
@Override
public void inject(Object hydratedState, Object value) {
( (Object[] ) hydratedState )[ attributeNumber() ] = value;
( (Object[] ) hydratedState )[ subAttributeNumber ] = value;
}
};
}

View File

@ -24,22 +24,43 @@
package org.hibernate.tuple.component;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.tuple.BaselineAttributeInformation;
import org.hibernate.type.CompositeType;
/**
* @author Steve Ebersole
*/
public class CompositionBasedCompositionAttribute
extends AbstractCompositionAttribute {
public class CompositionBasedCompositionAttribute extends AbstractCompositionAttribute {
public CompositionBasedCompositionAttribute(
CompositionDefinition source,
AbstractCompositionAttribute source,
SessionFactoryImplementor sessionFactory,
int attributeNumber,
int entityBasedAttributeNumber,
String attributeName,
CompositeType attributeType,
int columnStartPosition,
BaselineAttributeInformation baselineInfo) {
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
super(
source,
sessionFactory,
entityBasedAttributeNumber,
attributeName,
attributeType,
columnStartPosition,
baselineInfo
);
}
@Override
protected EntityPersister locateOwningPersister() {
final AbstractCompositionAttribute source = (AbstractCompositionAttribute) getSource();
if ( EntityDefinition.class.isInstance( source.getSource() ) ) {
return EntityDefinition.class.cast( source.getSource() ).getEntityPersister();
}
else {
return AbstractCompositionAttribute.class.cast( source.getSource() ).locateOwningPersister();
}
}
}

View File

@ -44,6 +44,11 @@ public class EntityBasedCompositionAttribute
String attributeName,
CompositeType attributeType,
BaselineAttributeInformation baselineInfo) {
super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo );
super( source, factory, attributeNumber, attributeName, attributeType, 0, baselineInfo );
}
@Override
protected EntityPersister locateOwningPersister() {
return (EntityPersister) getSource();
}
}

View File

@ -115,6 +115,10 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
return new NonPojoInstrumentationMetadata( null );
}
@Override
public void generateEntityDefinition() {
}
@Override
public void postInstantiate() throws MappingException {

View File

@ -77,6 +77,10 @@ public class CustomPersister implements EntityPersister {
return Custom.class;
}
@Override
public void generateEntityDefinition() {
}
public void postInstantiate() throws MappingException {}
public String getEntityName() {

View File

@ -26,7 +26,7 @@ package org.hibernate.test.loadplans.plans;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
import org.hibernate.loader.plan2.spi.BidirectionalEntityReference;
import org.hibernate.test.annotations.Country;
import org.hibernate.test.annotations.collectionelement.Boy;
import org.hibernate.test.annotations.collectionelement.Matrix;
@ -226,18 +226,19 @@ public class LoadPlanStructureAssertionTest extends BaseUnitTestCase {
FetchSource.class,
cardFieldElementGraph.getIdentifierDescription()
);
assertEquals( 2, cardFieldElementGraphIdAsFetchSource.getFetches().length );
assertEquals( 1, cardFieldElementGraphIdAsFetchSource.getFetches().length );
assertEquals( 1, cardFieldElementGraphIdAsFetchSource.getBidirectionalEntityReferences().length );
BidirectionalEntityFetch circularCardFetch = assertTyping(
BidirectionalEntityFetch.class,
cardFieldElementGraphIdAsFetchSource.getFetches()[0]
BidirectionalEntityReference circularCardFetch = assertTyping(
BidirectionalEntityReference.class,
cardFieldElementGraphIdAsFetchSource.getBidirectionalEntityReferences()[0]
);
assertSame( circularCardFetch.getTargetEntityReference(), cardReturn );
// the fetch above is to the other key-many-to-one for CardField.primaryKey composite: key
EntityFetch keyFetch = assertTyping(
EntityFetch.class,
cardFieldElementGraphIdAsFetchSource.getFetches()[1]
cardFieldElementGraphIdAsFetchSource.getFetches()[0]
);
assertEquals( Key.class.getName(), keyFetch.getEntityPersister().getEntityName() );
}

View File

@ -143,6 +143,10 @@ public class PersisterClassProviderTest {
return new NonPojoInstrumentationMetadata( getEntityName() );
}
@Override
public void generateEntityDefinition() {
}
@Override
public void postInstantiate() throws MappingException {