HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
This commit is contained in:
parent
4420fa71d6
commit
f111600e1f
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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>" )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>" )
|
||||
);
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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() )
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -33,4 +33,9 @@ public class SimpleEntityIdentifierDescriptionImpl implements EntityIdentifierDe
|
|||
public boolean hasFetches() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBidirectionalEntityReferences() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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,27 +140,31 @@ public abstract class AbstractRowReader implements RowReader {
|
|||
ResultSetProcessingContextImpl context,
|
||||
FetchSource fetchSource,
|
||||
Map<EntityReference,EntityReferenceInitializer> initializerByEntityReference) throws SQLException {
|
||||
// Resolve any bidirectional entity references first.
|
||||
for ( BidirectionalEntityReference bidirectionalEntityReference : fetchSource.getBidirectionalEntityReferences() ) {
|
||||
final EntityReferenceInitializer targetEntityReferenceInitializer = initializerByEntityReference.get(
|
||||
bidirectionalEntityReference.getTargetEntityReference()
|
||||
);
|
||||
resolveEntityKey(
|
||||
resultSet,
|
||||
context,
|
||||
targetEntityReferenceInitializer,
|
||||
initializerByEntityReference
|
||||
);
|
||||
targetEntityReferenceInitializer.hydrateEntityState( resultSet, context );
|
||||
}
|
||||
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()
|
||||
);
|
||||
}
|
||||
else {
|
||||
targetEntityReferenceInitializer = initializerByEntityReference.get( entityFetch );
|
||||
}
|
||||
if ( targetEntityReferenceInitializer != null ) {
|
||||
final EntityReferenceInitializer entityReferenceInitializer = initializerByEntityReference.get( entityFetch );
|
||||
if ( entityReferenceInitializer != null ) {
|
||||
resolveEntityKey(
|
||||
resultSet,
|
||||
context,
|
||||
targetEntityReferenceInitializer,
|
||||
entityReferenceInitializer,
|
||||
initializerByEntityReference
|
||||
);
|
||||
targetEntityReferenceInitializer.hydrateEntityState( resultSet, context );
|
||||
entityReferenceInitializer.hydrateEntityState( resultSet, context );
|
||||
}
|
||||
}
|
||||
else if ( CompositeFetch.class.isInstance( fetch ) ) {
|
||||
|
|
|
@ -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
|
||||
*
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
return new NonPojoInstrumentationMetadata( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEntityDefinition() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInstantiate() throws MappingException {
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ public class CustomPersister implements EntityPersister {
|
|||
return Custom.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEntityDefinition() {
|
||||
}
|
||||
|
||||
public void postInstantiate() throws MappingException {}
|
||||
|
||||
public String getEntityName() {
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
@ -143,6 +143,10 @@ public class PersisterClassProviderTest {
|
|||
return new NonPojoInstrumentationMetadata( getEntityName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEntityDefinition() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInstantiate() throws MappingException {
|
||||
|
||||
|
|
Loading…
Reference in New Issue