HHH-7841 - Redesign Loader
HHH-7841 - Redesign Loader HHH-7841 - Redesign Loader HHH-7841 - Redesign Loader
This commit is contained in:
parent
7bd9ba2adf
commit
043d618c03
|
@ -56,12 +56,11 @@ public abstract class AbstractJoinableAssociationImpl implements JoinableAssocia
|
||||||
EntityReference currentEntityReference,
|
EntityReference currentEntityReference,
|
||||||
CollectionReference currentCollectionReference,
|
CollectionReference currentCollectionReference,
|
||||||
String withClause,
|
String withClause,
|
||||||
boolean isNullable,
|
|
||||||
boolean hasRestriction,
|
boolean hasRestriction,
|
||||||
Map<String, Filter> enabledFilters) throws MappingException {
|
Map<String, Filter> enabledFilters) throws MappingException {
|
||||||
this.propertyPath = currentFetch.getPropertyPath();
|
this.propertyPath = currentFetch.getPropertyPath();
|
||||||
if ( currentFetch.getFetchStrategy().getStyle() == FetchStyle.JOIN ) {
|
if ( currentFetch.getFetchStrategy().getStyle() == FetchStyle.JOIN ) {
|
||||||
joinType = isNullable ? JoinType.LEFT_OUTER_JOIN : JoinType.INNER_JOIN;
|
joinType = currentFetch.isNullable() ? JoinType.LEFT_OUTER_JOIN : JoinType.INNER_JOIN;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
joinType = JoinType.NONE;
|
joinType = JoinType.NONE;
|
||||||
|
|
|
@ -56,7 +56,6 @@ public class CollectionJoinableAssociationImpl extends AbstractJoinableAssociati
|
||||||
currentEntityReference,
|
currentEntityReference,
|
||||||
collectionFetch,
|
collectionFetch,
|
||||||
withClause,
|
withClause,
|
||||||
true,
|
|
||||||
hasRestriction,
|
hasRestriction,
|
||||||
enabledFilters
|
enabledFilters
|
||||||
);
|
);
|
||||||
|
|
|
@ -48,7 +48,6 @@ public class EntityJoinableAssociationImpl extends AbstractJoinableAssociationIm
|
||||||
EntityFetch entityFetch,
|
EntityFetch entityFetch,
|
||||||
CollectionReference currentCollectionReference,
|
CollectionReference currentCollectionReference,
|
||||||
String withClause,
|
String withClause,
|
||||||
boolean isNullable,
|
|
||||||
boolean hasRestriction,
|
boolean hasRestriction,
|
||||||
Map<String, Filter> enabledFilters) throws MappingException {
|
Map<String, Filter> enabledFilters) throws MappingException {
|
||||||
super(
|
super(
|
||||||
|
@ -56,7 +55,6 @@ public class EntityJoinableAssociationImpl extends AbstractJoinableAssociationIm
|
||||||
entityFetch,
|
entityFetch,
|
||||||
currentCollectionReference,
|
currentCollectionReference,
|
||||||
withClause,
|
withClause,
|
||||||
isNullable,
|
|
||||||
hasRestriction,
|
hasRestriction,
|
||||||
enabledFilters
|
enabledFilters
|
||||||
);
|
);
|
||||||
|
|
|
@ -149,14 +149,10 @@ public class EntityLoadQueryBuilderImpl implements LoadQueryBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startingEntityFetch(EntityFetch entityFetch) {
|
public void startingEntityFetch(EntityFetch entityFetch) {
|
||||||
final OuterJoinLoadable ownerPersister = (OuterJoinLoadable) entityFetch.getOwner().retrieveFetchSourcePersister();
|
|
||||||
final int propertyNumber = ownerPersister.getEntityMetamodel().getPropertyIndex( entityFetch.getOwnerPropertyName() );
|
|
||||||
final boolean isNullable = ownerPersister.isSubclassPropertyNullable( propertyNumber );
|
|
||||||
EntityJoinableAssociationImpl assoc = new EntityJoinableAssociationImpl(
|
EntityJoinableAssociationImpl assoc = new EntityJoinableAssociationImpl(
|
||||||
entityFetch,
|
entityFetch,
|
||||||
getCurrentCollectionReference(),
|
getCurrentCollectionReference(),
|
||||||
"", // getWithClause( entityFetch.getPropertyPath() )
|
"", // getWithClause( entityFetch.getPropertyPath() )
|
||||||
isNullable,
|
|
||||||
false, // hasRestriction( entityFetch.getPropertyPath() )
|
false, // hasRestriction( entityFetch.getPropertyPath() )
|
||||||
loadQueryInfluencers.getEnabledFilters()
|
loadQueryInfluencers.getEnabledFilters()
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.cfg.NotYetImplementedException;
|
import org.hibernate.cfg.NotYetImplementedException;
|
||||||
import org.hibernate.engine.internal.JoinHelper;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.loader.CollectionAliases;
|
import org.hibernate.loader.CollectionAliases;
|
||||||
|
@ -36,6 +35,8 @@ import org.hibernate.loader.EntityAliases;
|
||||||
import org.hibernate.loader.GeneratedCollectionAliases;
|
import org.hibernate.loader.GeneratedCollectionAliases;
|
||||||
import org.hibernate.loader.plan.spi.CollectionReference;
|
import org.hibernate.loader.plan.spi.CollectionReference;
|
||||||
import org.hibernate.loader.plan.spi.CollectionReturn;
|
import org.hibernate.loader.plan.spi.CollectionReturn;
|
||||||
|
import org.hibernate.loader.plan.spi.CompositeElementGraph;
|
||||||
|
import org.hibernate.loader.plan.spi.CompositeIndexGraph;
|
||||||
import org.hibernate.loader.plan.spi.EntityReference;
|
import org.hibernate.loader.plan.spi.EntityReference;
|
||||||
import org.hibernate.loader.plan.spi.EntityReturn;
|
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||||
import org.hibernate.loader.plan.spi.Fetch;
|
import org.hibernate.loader.plan.spi.Fetch;
|
||||||
|
@ -46,7 +47,6 @@ import org.hibernate.loader.spi.LoadQueryAliasResolutionContext;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Loadable;
|
import org.hibernate.persister.entity.Loadable;
|
||||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,9 +214,18 @@ public class LoadQueryAliasResolutionContextImpl implements LoadQueryAliasResolu
|
||||||
if ( EntityReference.class.isInstance( currentFetch.getOwner() ) ) {
|
if ( EntityReference.class.isInstance( currentFetch.getOwner() ) ) {
|
||||||
lhsAlias = resolveEntityTableAlias( (EntityReference) currentFetch.getOwner() );
|
lhsAlias = resolveEntityTableAlias( (EntityReference) currentFetch.getOwner() );
|
||||||
}
|
}
|
||||||
else {
|
else if ( CompositeElementGraph.class.isInstance( currentFetch.getOwner() ) ) {
|
||||||
throw new NotYetImplementedException( "Cannot determine LHS alias for a FetchOwner that is not an EntityReference yet." );
|
CompositeElementGraph compositeElementGraph = (CompositeElementGraph) currentFetch.getOwner();
|
||||||
|
lhsAlias = resolveCollectionTableAlias( compositeElementGraph.getCollectionReference() );
|
||||||
}
|
}
|
||||||
|
else if ( CompositeIndexGraph.class.isInstance( currentFetch.getOwner() ) ) {
|
||||||
|
CompositeIndexGraph compositeIndexGraph = (CompositeIndexGraph) currentFetch.getOwner();
|
||||||
|
lhsAlias = resolveCollectionTableAlias( compositeIndexGraph.getCollectionReference() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new NotYetImplementedException( "Cannot determine LHS alias for FetchOwner." );
|
||||||
|
}
|
||||||
|
final String[] aliasedLhsColumnNames = StringHelper.qualify( lhsAlias, currentFetch.getColumnNames() );
|
||||||
final String rhsAlias;
|
final String rhsAlias;
|
||||||
if ( EntityReference.class.isInstance( currentFetch ) ) {
|
if ( EntityReference.class.isInstance( currentFetch ) ) {
|
||||||
rhsAlias = resolveEntityTableAlias( (EntityReference) currentFetch );
|
rhsAlias = resolveEntityTableAlias( (EntityReference) currentFetch );
|
||||||
|
@ -229,15 +238,6 @@ public class LoadQueryAliasResolutionContextImpl implements LoadQueryAliasResolu
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: can't this be found in CollectionAliases or EntityAliases? should be moved to LoadQueryAliasResolutionContextImpl
|
// TODO: can't this be found in CollectionAliases or EntityAliases? should be moved to LoadQueryAliasResolutionContextImpl
|
||||||
final OuterJoinLoadable fetchSourcePersister = (OuterJoinLoadable) currentFetch.getOwner().retrieveFetchSourcePersister();
|
|
||||||
final int propertyNumber = fetchSourcePersister.getEntityMetamodel().getPropertyIndex( currentFetch.getOwnerPropertyName() );
|
|
||||||
final String[] aliasedLhsColumnNames = JoinHelper.getAliasedLHSColumnNames(
|
|
||||||
joinableAssociation.getAssociationType(),
|
|
||||||
lhsAlias,
|
|
||||||
propertyNumber,
|
|
||||||
fetchSourcePersister,
|
|
||||||
sessionFactory
|
|
||||||
);
|
|
||||||
|
|
||||||
aliases = new JoinableAssociationAliasesImpl( lhsAlias, aliasedLhsColumnNames, rhsAlias );
|
aliases = new JoinableAssociationAliasesImpl( lhsAlias, aliasedLhsColumnNames, rhsAlias );
|
||||||
aliasesByJoinableAssociation.put( joinableAssociation, aliases );
|
aliasesByJoinableAssociation.put( joinableAssociation, aliases );
|
||||||
|
|
|
@ -27,20 +27,24 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
||||||
|
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
||||||
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner {
|
public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner {
|
||||||
private final LockMode lockMode;
|
|
||||||
|
|
||||||
private List<Fetch> fetches;
|
private List<Fetch> fetches;
|
||||||
|
|
||||||
public AbstractFetchOwner(SessionFactoryImplementor factory, LockMode lockMode) {
|
public AbstractFetchOwner(SessionFactoryImplementor factory) {
|
||||||
super( factory );
|
super( factory );
|
||||||
this.lockMode = lockMode;
|
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,11 +54,10 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
|
||||||
/**
|
/**
|
||||||
* A "copy" constructor. Used while making clones/copies of this.
|
* A "copy" constructor. Used while making clones/copies of this.
|
||||||
*
|
*
|
||||||
* @param original
|
* @param original - the original object to copy.
|
||||||
*/
|
*/
|
||||||
protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) {
|
protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) {
|
||||||
super( original );
|
super( original );
|
||||||
this.lockMode = original.lockMode;
|
|
||||||
validate();
|
validate();
|
||||||
|
|
||||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
||||||
|
@ -62,6 +65,7 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
|
||||||
this.fetches = Collections.emptyList();
|
this.fetches = Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// TODO: don't think this is correct...
|
||||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
||||||
for ( Fetch fetch : fetches ) {
|
for ( Fetch fetch : fetches ) {
|
||||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
||||||
|
@ -71,11 +75,6 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
||||||
}
|
}
|
||||||
|
|
||||||
public LockMode getLockMode() {
|
|
||||||
return lockMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addFetch(Fetch fetch) {
|
public void addFetch(Fetch fetch) {
|
||||||
if ( fetch.getOwner() != this ) {
|
if ( fetch.getOwner() != this ) {
|
||||||
throw new IllegalArgumentException( "Fetch and owner did not match" );
|
throw new IllegalArgumentException( "Fetch and owner did not match" );
|
||||||
|
@ -92,4 +91,55 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet
|
||||||
public Fetch[] getFetches() {
|
public Fetch[] getFetches() {
|
||||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract FetchOwnerDelegate getFetchOwnerDelegate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable(Fetch fetch) {
|
||||||
|
return getFetchOwnerDelegate().isNullable( fetch );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
return getFetchOwnerDelegate().getType( fetch );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
return getFetchOwnerDelegate().getColumnNames( fetch );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionFetch buildCollectionFetch(
|
||||||
|
AssociationAttributeDefinition attributeDefinition,
|
||||||
|
FetchStrategy fetchStrategy,
|
||||||
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
return LoadPlanBuildingHelper.buildStandardCollectionFetch(
|
||||||
|
this,
|
||||||
|
attributeDefinition,
|
||||||
|
fetchStrategy,
|
||||||
|
loadPlanBuildingContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityFetch buildEntityFetch(
|
||||||
|
AssociationAttributeDefinition attributeDefinition,
|
||||||
|
FetchStrategy fetchStrategy,
|
||||||
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
||||||
|
this,
|
||||||
|
attributeDefinition,
|
||||||
|
fetchStrategy,
|
||||||
|
loadPlanBuildingContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompositeFetch buildCompositeFetch(
|
||||||
|
CompositionDefinition attributeDefinition,
|
||||||
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
|
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -42,11 +41,10 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
|
||||||
|
|
||||||
public AbstractSingularAttributeFetch(
|
public AbstractSingularAttributeFetch(
|
||||||
SessionFactoryImplementor factory,
|
SessionFactoryImplementor factory,
|
||||||
LockMode lockMode,
|
|
||||||
FetchOwner owner,
|
FetchOwner owner,
|
||||||
String ownerProperty,
|
String ownerProperty,
|
||||||
FetchStrategy fetchStrategy) {
|
FetchStrategy fetchStrategy) {
|
||||||
super( factory, lockMode );
|
super( factory );
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.ownerProperty = ownerProperty;
|
this.ownerProperty = ownerProperty;
|
||||||
this.fetchStrategy = fetchStrategy;
|
this.fetchStrategy = fetchStrategy;
|
||||||
|
@ -77,6 +75,16 @@ public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner
|
||||||
return ownerProperty;
|
return ownerProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return owner.isNullable( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames() {
|
||||||
|
return owner.getColumnNames( this );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchStrategy getFetchStrategy() {
|
public FetchStrategy getFetchStrategy() {
|
||||||
return fetchStrategy;
|
return fetchStrategy;
|
||||||
|
|
|
@ -28,8 +28,10 @@ import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
|
import org.hibernate.engine.internal.JoinHelper;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
||||||
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,6 +76,16 @@ public class CollectionFetch extends AbstractCollectionReference implements Fetc
|
||||||
return getPropertyPath().getProperty();
|
return getPropertyPath().getProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames() {
|
||||||
|
return getOwner().getColumnNames( this );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchStrategy getFetchStrategy() {
|
public FetchStrategy getFetchStrategy() {
|
||||||
return fetchStrategy;
|
return fetchStrategy;
|
||||||
|
|
|
@ -1,29 +1,24 @@
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.persister.collection.QueryableCollection;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CompositeElementGraph extends AbstractPlanNode implements FetchableCollectionElement {
|
public class CompositeElementGraph extends AbstractFetchOwner implements FetchableCollectionElement {
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
private final CollectionPersister collectionPersister;
|
private final CollectionPersister collectionPersister;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
private List<Fetch> fetches;
|
|
||||||
|
|
||||||
public CompositeElementGraph(
|
public CompositeElementGraph(
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
@ -34,39 +29,24 @@ public class CompositeElementGraph extends AbstractPlanNode implements Fetchable
|
||||||
this.collectionReference = collectionReference;
|
this.collectionReference = collectionReference;
|
||||||
this.collectionPersister = collectionReference.getCollectionPersister();
|
this.collectionPersister = collectionReference.getCollectionPersister();
|
||||||
this.propertyPath = collectionPath.append( "<elements>" );
|
this.propertyPath = collectionPath.append( "<elements>" );
|
||||||
|
this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate(
|
||||||
|
sessionFactory,
|
||||||
|
(CompositeType) collectionPersister.getElementType(),
|
||||||
|
( (QueryableCollection) collectionPersister ).getElementColumnNames()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompositeElementGraph(CompositeElementGraph original, CopyContext copyContext) {
|
public CompositeElementGraph(CompositeElementGraph original, CopyContext copyContext) {
|
||||||
super( original );
|
super( original, copyContext );
|
||||||
this.collectionReference = original.collectionReference;
|
this.collectionReference = original.collectionReference;
|
||||||
this.collectionPersister = original.collectionPersister;
|
this.collectionPersister = original.collectionPersister;
|
||||||
this.propertyPath = original.propertyPath;
|
this.propertyPath = original.propertyPath;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
|
||||||
if ( fetches == null || fetches.size() == 0 ) {
|
|
||||||
this.fetches = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
|
||||||
for ( Fetch fetch : fetches ) {
|
|
||||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
|
||||||
}
|
|
||||||
this.fetches = fetchesCopy;
|
|
||||||
}
|
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFetch(Fetch fetch) {
|
public CollectionReference getCollectionReference() {
|
||||||
if ( fetches == null ) {
|
return collectionReference;
|
||||||
fetches = new ArrayList<Fetch>();
|
|
||||||
}
|
|
||||||
fetches.add( fetch );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fetch[] getFetches() {
|
|
||||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,6 +63,16 @@ public class CompositeElementGraph extends AbstractPlanNode implements Fetchable
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompositeElementGraph makeCopy(CopyContext copyContext) {
|
||||||
|
return new CompositeElementGraph( this, copyContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollectionFetch buildCollectionFetch(
|
public CollectionFetch buildCollectionFetch(
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
AssociationAttributeDefinition attributeDefinition,
|
||||||
|
@ -90,29 +80,4 @@ public class CompositeElementGraph extends AbstractPlanNode implements Fetchable
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
LoadPlanBuildingContext loadPlanBuildingContext) {
|
||||||
throw new HibernateException( "Collection composite element cannot define collections" );
|
throw new HibernateException( "Collection composite element cannot define collections" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeElementGraph makeCopy(CopyContext copyContext) {
|
|
||||||
return new CompositeElementGraph( this, copyContext );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@ package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
@ -37,6 +35,7 @@ import org.hibernate.loader.spi.ResultSetProcessingContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -44,15 +43,28 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
public class CompositeFetch extends AbstractSingularAttributeFetch {
|
public class CompositeFetch extends AbstractSingularAttributeFetch {
|
||||||
public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||||
|
|
||||||
|
private final FetchOwnerDelegate delegate;
|
||||||
|
|
||||||
public CompositeFetch(
|
public CompositeFetch(
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
FetchOwner owner,
|
FetchOwner owner,
|
||||||
String ownerProperty) {
|
String ownerProperty) {
|
||||||
super( sessionFactory, LockMode.NONE, owner, ownerProperty, FETCH_PLAN );
|
super( sessionFactory, owner, ownerProperty, FETCH_PLAN );
|
||||||
|
this.delegate = new CompositeFetchOwnerDelegate(
|
||||||
|
sessionFactory,
|
||||||
|
(CompositeType) getOwner().getType( this ),
|
||||||
|
getOwner().getColumnNames( this )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompositeFetch(CompositeFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
|
public CompositeFetch(CompositeFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) {
|
||||||
super( original, copyContext, fetchOwnerCopy );
|
super( original, copyContext, fetchOwnerCopy );
|
||||||
|
this.delegate = original.getFetchOwnerDelegate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* 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.plan.spi;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
|
import org.hibernate.persister.walking.spi.WalkingException;
|
||||||
|
import org.hibernate.type.CompositeType;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class CompositeFetchOwnerDelegate implements FetchOwnerDelegate {
|
||||||
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
|
private final CompositeType compositeType;
|
||||||
|
private final String[] columnNames;
|
||||||
|
|
||||||
|
public CompositeFetchOwnerDelegate(
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
CompositeType compositeType,
|
||||||
|
String[] columnNames) {
|
||||||
|
this.sessionFactory = sessionFactory;
|
||||||
|
this.compositeType = compositeType;
|
||||||
|
this.columnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable(Fetch fetch) {
|
||||||
|
return compositeType.getPropertyNullability()[ determinePropertyIndex( fetch ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
return compositeType.getSubtypes()[ determinePropertyIndex( fetch ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
// TODO: probably want to cache this
|
||||||
|
int begin = 0;
|
||||||
|
String[] subColumnNames = null;
|
||||||
|
for ( int i = 0; i < compositeType.getSubtypes().length; i++ ) {
|
||||||
|
final int columnSpan = compositeType.getSubtypes()[i].getColumnSpan( sessionFactory );
|
||||||
|
subColumnNames = ArrayHelper.slice( columnNames, begin, columnSpan );
|
||||||
|
if ( compositeType.getPropertyNames()[ i ].equals( fetch.getOwnerPropertyName() ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
begin += columnSpan;
|
||||||
|
}
|
||||||
|
return subColumnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int determinePropertyIndex(Fetch fetch) {
|
||||||
|
// TODO: probably want to cache this
|
||||||
|
final String[] subAttributeNames = compositeType.getPropertyNames();
|
||||||
|
int subAttributeIndex = -1;
|
||||||
|
for ( int i = 0; i < subAttributeNames.length ; i++ ) {
|
||||||
|
if ( subAttributeNames[ i ].equals( fetch.getOwnerPropertyName() ) ) {
|
||||||
|
subAttributeIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( subAttributeIndex == -1 ) {
|
||||||
|
throw new WalkingException(
|
||||||
|
String.format(
|
||||||
|
"Owner property [%s] not found in composite properties [%s]",
|
||||||
|
fetch.getOwnerPropertyName(),
|
||||||
|
Arrays.asList( subAttributeNames )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return subAttributeIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,24 @@
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.persister.collection.QueryableCollection;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.type.CompositeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex {
|
public class CompositeIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex {
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
private final CollectionPersister collectionPersister;
|
private final CollectionPersister collectionPersister;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
private List<Fetch> fetches;
|
|
||||||
|
|
||||||
public CompositeIndexGraph(
|
public CompositeIndexGraph(
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
|
@ -33,39 +28,19 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCo
|
||||||
this.collectionReference = collectionReference;
|
this.collectionReference = collectionReference;
|
||||||
this.collectionPersister = collectionReference.getCollectionPersister();
|
this.collectionPersister = collectionReference.getCollectionPersister();
|
||||||
this.propertyPath = propertyPath.append( "<index>" );
|
this.propertyPath = propertyPath.append( "<index>" );
|
||||||
|
this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate(
|
||||||
|
sessionFactory,
|
||||||
|
(CompositeType) collectionPersister.getIndexType(),
|
||||||
|
( (QueryableCollection) collectionPersister ).getIndexColumnNames()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CompositeIndexGraph(CompositeIndexGraph original, CopyContext copyContext) {
|
protected CompositeIndexGraph(CompositeIndexGraph original, CopyContext copyContext) {
|
||||||
super( original );
|
super( original, copyContext );
|
||||||
this.collectionReference = original.collectionReference;
|
this.collectionReference = original.collectionReference;
|
||||||
this.collectionPersister = original.collectionPersister;
|
this.collectionPersister = original.collectionPersister;
|
||||||
this.propertyPath = original.propertyPath;
|
this.propertyPath = original.propertyPath;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
|
||||||
if ( fetches == null || fetches.size() == 0 ) {
|
|
||||||
this.fetches = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
|
||||||
for ( Fetch fetch : fetches ) {
|
|
||||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
|
||||||
}
|
|
||||||
this.fetches = fetchesCopy;
|
|
||||||
}
|
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addFetch(Fetch fetch) {
|
|
||||||
if ( fetches == null ) {
|
|
||||||
fetches = new ArrayList<Fetch>();
|
|
||||||
}
|
|
||||||
fetches.add( fetch );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fetch[] getFetches() {
|
|
||||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,12 +52,25 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCo
|
||||||
return collectionPersister.getOwnerEntityPersister();
|
return collectionPersister.getOwnerEntityPersister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CollectionReference getCollectionReference() {
|
||||||
|
return collectionReference;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyPath getPropertyPath() {
|
public PropertyPath getPropertyPath() {
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public CompositeIndexGraph makeCopy(CopyContext copyContext) {
|
||||||
|
return new CompositeIndexGraph( this, copyContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
public CollectionFetch buildCollectionFetch(
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
AssociationAttributeDefinition attributeDefinition,
|
||||||
FetchStrategy fetchStrategy,
|
FetchStrategy fetchStrategy,
|
||||||
|
@ -90,28 +78,4 @@ public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCo
|
||||||
throw new HibernateException( "Composite index cannot define collections" );
|
throw new HibernateException( "Composite index cannot define collections" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeIndexGraph makeCopy(CopyContext copyContext) {
|
|
||||||
return new CompositeIndexGraph( this, copyContext );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,23 @@
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EntityElementGraph extends AbstractPlanNode implements FetchableCollectionElement, EntityReference {
|
public class EntityElementGraph extends AbstractFetchOwner implements FetchableCollectionElement, EntityReference {
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final CollectionPersister collectionPersister;
|
private final CollectionPersister collectionPersister;
|
||||||
private final AssociationType elementType;
|
private final AssociationType elementType;
|
||||||
private final EntityPersister elementPersister;
|
private final EntityPersister elementPersister;
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
private List<Fetch> fetches;
|
|
||||||
|
|
||||||
private IdentifierDescription identifierDescription;
|
private IdentifierDescription identifierDescription;
|
||||||
|
|
||||||
|
@ -40,30 +31,19 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchableCol
|
||||||
this.collectionPersister = collectionReference.getCollectionPersister();
|
this.collectionPersister = collectionReference.getCollectionPersister();
|
||||||
this.elementType = (AssociationType) collectionPersister.getElementType();
|
this.elementType = (AssociationType) collectionPersister.getElementType();
|
||||||
this.elementPersister = (EntityPersister) this.elementType.getAssociatedJoinable( sessionFactory() );
|
this.elementPersister = (EntityPersister) this.elementType.getAssociatedJoinable( sessionFactory() );
|
||||||
this.propertyPath = collectionPath.append( "<elements>" );
|
this.propertyPath = collectionPath;
|
||||||
|
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( elementPersister );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityElementGraph(EntityElementGraph original, CopyContext copyContext) {
|
public EntityElementGraph(EntityElementGraph original, CopyContext copyContext) {
|
||||||
super( original );
|
super( original, copyContext );
|
||||||
|
|
||||||
this.collectionReference = original.collectionReference;
|
this.collectionReference = original.collectionReference;
|
||||||
this.collectionPersister = original.collectionReference.getCollectionPersister();
|
this.collectionPersister = original.collectionReference.getCollectionPersister();
|
||||||
this.elementType = original.elementType;
|
this.elementType = original.elementType;
|
||||||
this.elementPersister = original.elementPersister;
|
this.elementPersister = original.elementPersister;
|
||||||
this.propertyPath = original.propertyPath;
|
this.propertyPath = original.propertyPath;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
|
||||||
if ( fetches == null || fetches.size() == 0 ) {
|
|
||||||
this.fetches = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
|
||||||
for ( Fetch fetch : fetches ) {
|
|
||||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
|
||||||
}
|
|
||||||
this.fetches = fetchesCopy;
|
|
||||||
}
|
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,19 +66,6 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchableCol
|
||||||
return identifierDescription;
|
return identifierDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addFetch(Fetch fetch) {
|
|
||||||
if ( fetches == null ) {
|
|
||||||
fetches = new ArrayList<Fetch>();
|
|
||||||
}
|
|
||||||
fetches.add( fetch );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fetch[] getFetches() {
|
|
||||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
||||||
}
|
}
|
||||||
|
@ -113,39 +80,6 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchableCol
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCollectionFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
||||||
this.identifierDescription = identifierDescription;
|
this.identifierDescription = identifierDescription;
|
||||||
|
@ -156,8 +90,18 @@ public class EntityElementGraph extends AbstractPlanNode implements FetchableCol
|
||||||
return new EntityElementGraph( this, copyContext );
|
return new EntityElementGraph( this, copyContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionReference getCollectionReference() {
|
||||||
|
return collectionReference;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")";
|
return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,21 +32,19 @@ import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference {
|
public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference, Fetch {
|
||||||
|
|
||||||
private final EntityType associationType;
|
private final EntityType associationType;
|
||||||
private final EntityPersister persister;
|
private final EntityPersister persister;
|
||||||
|
private final LockMode lockMode;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
|
|
||||||
private IdentifierDescription identifierDescription;
|
private IdentifierDescription identifierDescription;
|
||||||
|
|
||||||
|
@ -57,10 +55,12 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
||||||
String ownerProperty,
|
String ownerProperty,
|
||||||
EntityType entityType,
|
EntityType entityType,
|
||||||
FetchStrategy fetchStrategy) {
|
FetchStrategy fetchStrategy) {
|
||||||
super( sessionFactory, lockMode, owner, ownerProperty, fetchStrategy );
|
super( sessionFactory, owner, ownerProperty, fetchStrategy );
|
||||||
|
|
||||||
this.associationType = entityType;
|
this.associationType = entityType;
|
||||||
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() );
|
this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() );
|
||||||
|
this.lockMode = lockMode;
|
||||||
|
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( persister );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +73,8 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
||||||
super( original, copyContext, fetchOwnerCopy );
|
super( original, copyContext, fetchOwnerCopy );
|
||||||
this.associationType = original.associationType;
|
this.associationType = original.associationType;
|
||||||
this.persister = original.persister;
|
this.persister = original.persister;
|
||||||
|
this.lockMode = original.lockMode;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityType getAssociationType() {
|
public EntityType getAssociationType() {
|
||||||
|
@ -94,45 +96,16 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
||||||
return identifierDescription;
|
return identifierDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LockMode getLockMode() {
|
||||||
|
return lockMode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister retrieveFetchSourcePersister() {
|
public EntityPersister retrieveFetchSourcePersister() {
|
||||||
return persister;
|
return persister;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCollectionFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
||||||
this.identifierDescription = identifierDescription;
|
this.identifierDescription = identifierDescription;
|
||||||
|
@ -268,4 +241,9 @@ public class EntityFetch extends AbstractSingularAttributeFetch implements Entit
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingEntityFetch( this );
|
copyContext.getReturnGraphVisitationStrategy().finishingEntityFetch( this );
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* 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.plan.spi;
|
||||||
|
|
||||||
|
import org.hibernate.engine.internal.JoinHelper;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||||
|
import org.hibernate.type.AssociationType;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class EntityFetchOwnerDelegate implements FetchOwnerDelegate {
|
||||||
|
private final EntityPersister entityPersister;
|
||||||
|
|
||||||
|
public EntityFetchOwnerDelegate(EntityPersister entityPersister) {
|
||||||
|
this.entityPersister = entityPersister;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable(Fetch fetch) {
|
||||||
|
return entityPersister.getPropertyNullability()[ determinePropertyIndex( fetch ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
return entityPersister.getPropertyTypes()[ determinePropertyIndex( fetch ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
final OuterJoinLoadable outerJoinLoadable = (OuterJoinLoadable) entityPersister;
|
||||||
|
Type fetchType = getType( fetch );
|
||||||
|
if ( fetchType.isAssociationType() ) {
|
||||||
|
return JoinHelper.getLHSColumnNames(
|
||||||
|
(AssociationType) fetchType,
|
||||||
|
determinePropertyIndex( fetch ),
|
||||||
|
outerJoinLoadable,
|
||||||
|
outerJoinLoadable.getFactory()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return outerJoinLoadable.getPropertyColumnNames( determinePropertyIndex( fetch ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int determinePropertyIndex(Fetch fetch) {
|
||||||
|
return entityPersister.getEntityMetamodel().getPropertyIndex( fetch.getOwnerPropertyName() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,33 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EntityIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex, EntityReference {
|
public class EntityIndexGraph extends AbstractFetchOwner implements FetchableCollectionIndex, EntityReference {
|
||||||
private final CollectionReference collectionReference;
|
private final CollectionReference collectionReference;
|
||||||
private final CollectionPersister collectionPersister;
|
private final CollectionPersister collectionPersister;
|
||||||
private final AssociationType indexType;
|
private final AssociationType indexType;
|
||||||
private final EntityPersister indexPersister;
|
private final EntityPersister indexPersister;
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
private List<Fetch> fetches;
|
|
||||||
|
|
||||||
private IdentifierDescription identifierDescription;
|
private IdentifierDescription identifierDescription;
|
||||||
|
|
||||||
|
@ -63,28 +54,17 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchableColle
|
||||||
this.indexType = (AssociationType) collectionPersister.getIndexType();
|
this.indexType = (AssociationType) collectionPersister.getIndexType();
|
||||||
this.indexPersister = (EntityPersister) this.indexType.getAssociatedJoinable( sessionFactory() );
|
this.indexPersister = (EntityPersister) this.indexType.getAssociatedJoinable( sessionFactory() );
|
||||||
this.propertyPath = collectionPath.append( "<index>" ); // todo : do we want the <index> part?
|
this.propertyPath = collectionPath.append( "<index>" ); // todo : do we want the <index> part?
|
||||||
|
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( indexPersister );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityIndexGraph(EntityIndexGraph original, CopyContext copyContext) {
|
public EntityIndexGraph(EntityIndexGraph original, CopyContext copyContext) {
|
||||||
super( original );
|
super( original, copyContext );
|
||||||
this.collectionReference = original.collectionReference;
|
this.collectionReference = original.collectionReference;
|
||||||
this.collectionPersister = original.collectionReference.getCollectionPersister();
|
this.collectionPersister = original.collectionReference.getCollectionPersister();
|
||||||
this.indexType = original.indexType;
|
this.indexType = original.indexType;
|
||||||
this.indexPersister = original.indexPersister;
|
this.indexPersister = original.indexPersister;
|
||||||
this.propertyPath = original.propertyPath;
|
this.propertyPath = original.propertyPath;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
copyContext.getReturnGraphVisitationStrategy().startingFetches( original );
|
|
||||||
if ( fetches == null || fetches.size() == 0 ) {
|
|
||||||
this.fetches = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<Fetch> fetchesCopy = new ArrayList<Fetch>();
|
|
||||||
for ( Fetch fetch : fetches ) {
|
|
||||||
fetchesCopy.add( fetch.makeCopy( copyContext, this ) );
|
|
||||||
}
|
|
||||||
this.fetches = fetchesCopy;
|
|
||||||
}
|
|
||||||
copyContext.getReturnGraphVisitationStrategy().finishingFetches( original );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,19 +87,6 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchableColle
|
||||||
return identifierDescription;
|
return identifierDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addFetch(Fetch fetch) {
|
|
||||||
if ( fetches == null ) {
|
|
||||||
fetches = new ArrayList<Fetch>();
|
|
||||||
}
|
|
||||||
fetches.add( fetch );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fetch[] getFetches() {
|
|
||||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
||||||
}
|
}
|
||||||
|
@ -134,39 +101,6 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchableColle
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCollectionFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
public void injectIdentifierDescription(IdentifierDescription identifierDescription) {
|
||||||
this.identifierDescription = identifierDescription;
|
this.identifierDescription = identifierDescription;
|
||||||
|
@ -176,4 +110,9 @@ public class EntityIndexGraph extends AbstractPlanNode implements FetchableColle
|
||||||
public EntityIndexGraph makeCopy(CopyContext copyContext) {
|
public EntityIndexGraph makeCopy(CopyContext copyContext) {
|
||||||
return new EntityIndexGraph( this, copyContext );
|
return new EntityIndexGraph( this, copyContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,8 @@ import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper;
|
|
||||||
import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
|
||||||
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
|
||||||
|
|
||||||
import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext;
|
import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext;
|
||||||
|
|
||||||
|
@ -50,24 +46,32 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
|
||||||
|
|
||||||
private final PropertyPath propertyPath = new PropertyPath(); // its a root
|
private final PropertyPath propertyPath = new PropertyPath(); // its a root
|
||||||
|
|
||||||
|
private final LockMode lockMode;
|
||||||
|
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
|
|
||||||
private IdentifierDescription identifierDescription;
|
private IdentifierDescription identifierDescription;
|
||||||
|
|
||||||
public EntityReturn(
|
public EntityReturn(
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
String entityName) {
|
String entityName) {
|
||||||
super( sessionFactory, lockMode );
|
super( sessionFactory );
|
||||||
|
|
||||||
this.persister = sessionFactory.getEntityPersister( entityName );
|
this.persister = sessionFactory.getEntityPersister( entityName );
|
||||||
|
this.lockMode = lockMode;
|
||||||
|
this.fetchOwnerDelegate = new EntityFetchOwnerDelegate( persister );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EntityReturn(EntityReturn original, CopyContext copyContext) {
|
protected EntityReturn(EntityReturn original, CopyContext copyContext) {
|
||||||
super( original, copyContext );
|
super( original, copyContext );
|
||||||
this.persister = original.persister;
|
this.persister = original.persister;
|
||||||
|
this.lockMode = original.lockMode;
|
||||||
|
this.fetchOwnerDelegate = original.fetchOwnerDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LockMode getLockMode() {
|
public LockMode getLockMode() {
|
||||||
return super.getLockMode();
|
return lockMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,39 +103,6 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionFetch buildCollectionFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCollectionFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFetch buildEntityFetch(
|
|
||||||
AssociationAttributeDefinition attributeDefinition,
|
|
||||||
FetchStrategy fetchStrategy,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardEntityFetch(
|
|
||||||
this,
|
|
||||||
attributeDefinition,
|
|
||||||
fetchStrategy,
|
|
||||||
loadPlanBuildingContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompositeFetch buildCompositeFetch(
|
|
||||||
CompositionDefinition attributeDefinition,
|
|
||||||
LoadPlanBuildingContext loadPlanBuildingContext) {
|
|
||||||
return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
|
public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
|
||||||
EntityKey entityKey = getEntityKeyFromContext( context );
|
EntityKey entityKey = getEntityKeyFromContext( context );
|
||||||
|
@ -207,4 +178,9 @@ public class EntityReturn extends AbstractFetchOwner implements Return, EntityRe
|
||||||
public EntityReturn makeCopy(CopyContext copyContext) {
|
public EntityReturn makeCopy(CopyContext copyContext) {
|
||||||
return new EntityReturn( this, copyContext );
|
return new EntityReturn( this, copyContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FetchOwnerDelegate getFetchOwnerDelegate() {
|
||||||
|
return fetchOwnerDelegate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,10 @@ public interface Fetch extends CopyableFetch {
|
||||||
*/
|
*/
|
||||||
public String getOwnerPropertyName();
|
public String getOwnerPropertyName();
|
||||||
|
|
||||||
|
public boolean isNullable();
|
||||||
|
|
||||||
|
public String[] getColumnNames();
|
||||||
|
|
||||||
public FetchStrategy getFetchStrategy();
|
public FetchStrategy getFetchStrategy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract for owners of fetches. Any non-scalar return could be a fetch owner.
|
* Contract for owners of fetches. Any non-scalar return could be a fetch owner.
|
||||||
|
@ -56,6 +57,12 @@ public interface FetchOwner {
|
||||||
*/
|
*/
|
||||||
public Fetch[] getFetches();
|
public Fetch[] getFetches();
|
||||||
|
|
||||||
|
public Type getType(Fetch fetch);
|
||||||
|
|
||||||
|
public boolean isNullable(Fetch fetch);
|
||||||
|
|
||||||
|
public String[] getColumnNames(Fetch fetch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the asserted plan valid from this owner to a fetch?
|
* Is the asserted plan valid from this owner to a fetch?
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.plan.spi;
|
||||||
|
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public interface FetchOwnerDelegate {
|
||||||
|
|
||||||
|
public boolean isNullable(Fetch fetch);
|
||||||
|
|
||||||
|
public Type getType(Fetch fetch);
|
||||||
|
|
||||||
|
public String[] getColumnNames(Fetch fetch);
|
||||||
|
}
|
|
@ -23,10 +23,14 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.loader.plan.spi;
|
package org.hibernate.loader.plan.spi;
|
||||||
|
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface FetchableCollectionElement extends FetchOwner, CopyableReturn {
|
public interface FetchableCollectionElement extends FetchOwner, CopyableReturn {
|
||||||
@Override
|
@Override
|
||||||
public FetchableCollectionElement makeCopy(CopyContext copyContext);
|
public FetchableCollectionElement makeCopy(CopyContext copyContext);
|
||||||
|
|
||||||
|
public CollectionReference getCollectionReference();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,16 +49,20 @@ import org.hibernate.loader.plan.spi.AbstractSingularAttributeFetch;
|
||||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||||
import org.hibernate.loader.plan.spi.CollectionReference;
|
import org.hibernate.loader.plan.spi.CollectionReference;
|
||||||
import org.hibernate.loader.plan.spi.CollectionReturn;
|
import org.hibernate.loader.plan.spi.CollectionReturn;
|
||||||
|
import org.hibernate.loader.plan.spi.CompositeElementGraph;
|
||||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||||
|
import org.hibernate.loader.plan.spi.CompositeFetchOwnerDelegate;
|
||||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||||
import org.hibernate.loader.plan.spi.EntityReference;
|
import org.hibernate.loader.plan.spi.EntityReference;
|
||||||
import org.hibernate.loader.plan.spi.EntityReturn;
|
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||||
import org.hibernate.loader.plan.spi.Fetch;
|
import org.hibernate.loader.plan.spi.Fetch;
|
||||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||||
|
import org.hibernate.loader.plan.spi.FetchOwnerDelegate;
|
||||||
import org.hibernate.loader.plan.spi.IdentifierDescription;
|
import org.hibernate.loader.plan.spi.IdentifierDescription;
|
||||||
import org.hibernate.loader.plan.spi.Return;
|
import org.hibernate.loader.plan.spi.Return;
|
||||||
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
import org.hibernate.loader.spi.ResultSetProcessingContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.Loadable;
|
||||||
import org.hibernate.persister.spi.HydratedCompoundValueHandler;
|
import org.hibernate.persister.spi.HydratedCompoundValueHandler;
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
|
@ -66,9 +70,11 @@ import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.WalkingException;
|
import org.hibernate.persister.walking.spi.WalkingException;
|
||||||
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext;
|
import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext;
|
||||||
|
@ -192,7 +198,12 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
|
|
||||||
final FetchOwner identifierAttributeCollector;
|
final FetchOwner identifierAttributeCollector;
|
||||||
if ( entityIdentifierDefinition.isEncapsulated() ) {
|
if ( entityIdentifierDefinition.isEncapsulated() ) {
|
||||||
identifierAttributeCollector = new EncapsulatedIdentifierAttributeCollector( entityReference );
|
if ( entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getIdentifierType().isComponentType() ) {
|
||||||
|
identifierAttributeCollector = new EncapsulatedCompositeIdentifierAttributeCollector( entityReference );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
identifierAttributeCollector = new EncapsulatedIdentifierAttributeCollector( entityReference );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
identifierAttributeCollector = new NonEncapsulatedIdentifierAttributeCollector( entityReference );
|
identifierAttributeCollector = new NonEncapsulatedIdentifierAttributeCollector( entityReference );
|
||||||
|
@ -307,6 +318,35 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
// - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite
|
// - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startingCompositeElement(CompositionElementDefinition compositeElementDefinition) {
|
||||||
|
System.out.println(
|
||||||
|
String.format(
|
||||||
|
"%s Starting composite collection element for (%s)",
|
||||||
|
StringHelper.repeat( ">>", fetchOwnerStack.size() ),
|
||||||
|
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishingCompositeElement(CompositionElementDefinition compositeElementDefinition) {
|
||||||
|
// pop the current fetch owner, and make sure what we just popped represents this composition
|
||||||
|
final FetchOwner poppedFetchOwner = popFromStack();
|
||||||
|
|
||||||
|
if ( ! CompositeElementGraph.class.isInstance( poppedFetchOwner ) ) {
|
||||||
|
throw new WalkingException( "Mismatched FetchOwner from stack on pop" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE : not much else we can really check here atm since on the walking spi side we do not have path
|
||||||
|
|
||||||
|
log.tracef(
|
||||||
|
"%s Finished composite element for : %s",
|
||||||
|
StringHelper.repeat( "<<", fetchOwnerStack.size() ),
|
||||||
|
compositeElementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
||||||
// pop the current fetch owner, and make sure what we just popped represents this collection
|
// pop the current fetch owner, and make sure what we just popped represents this collection
|
||||||
|
@ -513,6 +553,11 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
return entityReference.getEntityPersister();
|
return entityReference.getEntityPersister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable(Fetch fetch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdentifierDescription getIdentifierDescription() {
|
public IdentifierDescription getIdentifierDescription() {
|
||||||
return entityReference.getIdentifierDescription();
|
return entityReference.getIdentifierDescription();
|
||||||
|
@ -596,6 +641,13 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static abstract class AbstractCompositeIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector {
|
||||||
|
|
||||||
|
public AbstractCompositeIdentifierAttributeCollector(EntityReference entityReference) {
|
||||||
|
super( entityReference );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static class EncapsulatedIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector {
|
protected static class EncapsulatedIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector {
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
|
|
||||||
|
@ -613,17 +665,76 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
return ( (Loadable) entityReference.getEntityPersister() ).getIdentifierColumnNames();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyPath getPropertyPath() {
|
public PropertyPath getPropertyPath() {
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class NonEncapsulatedIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector {
|
protected static class EncapsulatedCompositeIdentifierAttributeCollector extends AbstractCompositeIdentifierAttributeCollector {
|
||||||
private final PropertyPath propertyPath;
|
private final PropertyPath propertyPath;
|
||||||
|
|
||||||
|
public EncapsulatedCompositeIdentifierAttributeCollector(EntityReference entityReference) {
|
||||||
|
super( entityReference );
|
||||||
|
this.propertyPath = ( (FetchOwner) entityReference ).getPropertyPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IdentifierDescription buildIdentifierDescription() {
|
||||||
|
return new IdentifierDescriptionImpl(
|
||||||
|
entityReference,
|
||||||
|
identifierFetches.toArray( new AbstractSingularAttributeFetch[ identifierFetches.size() ] ),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyPath getPropertyPath() {
|
||||||
|
return propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
if ( !fetch.getOwnerPropertyName().equals( entityReference.getEntityPersister().getIdentifierPropertyName() ) ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"Fetch owner property name [%s] is not the same as the identifier property name [%s].",
|
||||||
|
fetch.getOwnerPropertyName(),
|
||||||
|
entityReference.getEntityPersister().getIdentifierPropertyName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return entityReference.getEntityPersister().getIdentifierType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
return ( (Loadable) entityReference.getEntityPersister() ).getIdentifierColumnNames();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class NonEncapsulatedIdentifierAttributeCollector extends AbstractCompositeIdentifierAttributeCollector {
|
||||||
|
private final PropertyPath propertyPath;
|
||||||
|
private final FetchOwnerDelegate fetchOwnerDelegate;
|
||||||
|
|
||||||
public NonEncapsulatedIdentifierAttributeCollector(EntityReference entityReference) {
|
public NonEncapsulatedIdentifierAttributeCollector(EntityReference entityReference) {
|
||||||
super( entityReference );
|
super( entityReference );
|
||||||
this.propertyPath = ( (FetchOwner) entityReference ).getPropertyPath().append( "<id>" );
|
this.propertyPath = ( (FetchOwner) entityReference ).getPropertyPath().append( "<id>" );
|
||||||
|
this.fetchOwnerDelegate = new CompositeFetchOwnerDelegate(
|
||||||
|
entityReference.getEntityPersister().getFactory(),
|
||||||
|
(CompositeType) entityReference.getEntityPersister().getIdentifierType(),
|
||||||
|
( (Loadable) entityReference.getEntityPersister() ).getIdentifierColumnNames()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -639,6 +750,24 @@ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilder
|
||||||
public PropertyPath getPropertyPath() {
|
public PropertyPath getPropertyPath() {
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Type getType(Fetch fetch) {
|
||||||
|
if ( !fetch.getOwnerPropertyName().equals( entityReference.getEntityPersister().getIdentifierPropertyName() ) ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"Fetch owner property name [%s] is not the same as the identifier property name [%s].",
|
||||||
|
fetch.getOwnerPropertyName(),
|
||||||
|
entityReference.getEntityPersister().getIdentifierPropertyName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return fetchOwnerDelegate.getType( fetch );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getColumnNames(Fetch fetch) {
|
||||||
|
return fetchOwnerDelegate.getColumnNames( fetch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IdentifierDescriptionImpl implements IdentifierDescription {
|
private static class IdentifierDescriptionImpl implements IdentifierDescription {
|
||||||
|
|
|
@ -80,10 +80,14 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Loadable;
|
import org.hibernate.persister.entity.Loadable;
|
||||||
import org.hibernate.persister.entity.PropertyMapping;
|
import org.hibernate.persister.entity.PropertyMapping;
|
||||||
import org.hibernate.persister.entity.Queryable;
|
import org.hibernate.persister.entity.Queryable;
|
||||||
|
import org.hibernate.persister.walking.internal.CompositionSingularSubAttributesHelper;
|
||||||
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.AttributeSource;
|
||||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
|
@ -1941,7 +1945,6 @@ public abstract class AbstractCollectionPersister
|
||||||
|
|
||||||
public abstract FilterAliasGenerator getFilterAliasGenerator(final String rootAlias);
|
public abstract FilterAliasGenerator getFilterAliasGenerator(final String rootAlias);
|
||||||
|
|
||||||
|
|
||||||
// ColectionDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ColectionDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2007,12 +2010,42 @@ public abstract class AbstractCollectionPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompositionDefinition toCompositeDefinition() {
|
public CompositionElementDefinition toCompositeElementDefinition() {
|
||||||
|
final String propertyName = role.substring( entityName.length() + 1 );
|
||||||
|
final int propertyIndex = ownerPersister.getEntityMetamodel().getPropertyIndex( propertyName );
|
||||||
|
|
||||||
if ( ! getType().isComponentType() ) {
|
if ( ! getType().isComponentType() ) {
|
||||||
throw new IllegalStateException( "Cannot treat entity collection element type as composite" );
|
throw new IllegalStateException( "Cannot treat entity collection element type as composite" );
|
||||||
}
|
}
|
||||||
// todo : implement
|
|
||||||
throw new NotYetImplementedException();
|
return new CompositionElementDefinition() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return getElementType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeSource getSource() {
|
||||||
|
// TODO: what if this is a collection w/in an encapsulated composition attribute?
|
||||||
|
// should return the encapsulated composition attribute instead???
|
||||||
|
return getOwnerEntityPersister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<AttributeDefinition> getAttributes() {
|
||||||
|
return CompositionSingularSubAttributesHelper.getCompositionElementSubAttributes( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionDefinition getCollectionDefinition() {
|
||||||
|
return AbstractCollectionPersister.this;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
|
||||||
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
|
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
|
||||||
import org.hibernate.cache.spi.entry.StructuredCacheEntry;
|
import org.hibernate.cache.spi.entry.StructuredCacheEntry;
|
||||||
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
||||||
import org.hibernate.cfg.NotYetImplementedException;
|
|
||||||
import org.hibernate.dialect.lock.LockingStrategy;
|
import org.hibernate.dialect.lock.LockingStrategy;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||||
|
@ -111,12 +110,7 @@ import org.hibernate.metamodel.relational.DerivedValue;
|
||||||
import org.hibernate.metamodel.relational.Value;
|
import org.hibernate.metamodel.relational.Value;
|
||||||
import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper;
|
import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper;
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
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.EncapsulatedEntityIdentifierDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.NonEncapsulatedEntityIdentifierDefinition;
|
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.property.BackrefPropertyAccessor;
|
import org.hibernate.property.BackrefPropertyAccessor;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
|
@ -132,7 +126,6 @@ import org.hibernate.sql.Update;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
import org.hibernate.type.ComponentType;
|
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
package org.hibernate.persister.walking.internal;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.hibernate.engine.FetchStrategy;
|
||||||
|
import org.hibernate.engine.FetchStyle;
|
||||||
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
|
import org.hibernate.engine.spi.CascadeStyles;
|
||||||
|
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
|
import org.hibernate.loader.PropertyPath;
|
||||||
|
import org.hibernate.persister.collection.QueryableCollection;
|
||||||
|
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||||
|
import org.hibernate.persister.spi.HydratedCompoundValueHandler;
|
||||||
|
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||||
|
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.CollectionDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.WalkingException;
|
||||||
|
import org.hibernate.type.AssociationType;
|
||||||
|
import org.hibernate.type.CompositeType;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class CompositionSingularSubAttributesHelper {
|
||||||
|
|
||||||
|
public static Iterable<AttributeDefinition> getIdentifierSubAttributes(
|
||||||
|
final AbstractEntityPersister entityPersister) {
|
||||||
|
return getSingularSubAttributes(
|
||||||
|
entityPersister,
|
||||||
|
entityPersister,
|
||||||
|
(CompositeType) entityPersister.getIdentifierType(),
|
||||||
|
entityPersister.getTableName(),
|
||||||
|
entityPersister.getRootTableIdentifierColumnNames()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Iterable<AttributeDefinition> getCompositionElementSubAttributes(
|
||||||
|
CompositionElementDefinition compositionElementDefinition) {
|
||||||
|
final QueryableCollection collectionPersister =
|
||||||
|
(QueryableCollection) compositionElementDefinition.getCollectionDefinition().getCollectionPersister();
|
||||||
|
return getSingularSubAttributes(
|
||||||
|
compositionElementDefinition.getSource(),
|
||||||
|
(OuterJoinLoadable) collectionPersister.getOwnerEntityPersister(),
|
||||||
|
(CompositeType) collectionPersister.getElementType(),
|
||||||
|
collectionPersister.getTableName(),
|
||||||
|
collectionPersister.getElementColumnNames()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Iterable<AttributeDefinition> getSingularSubAttributes(
|
||||||
|
final AttributeSource source,
|
||||||
|
final OuterJoinLoadable ownerEntityPersister,
|
||||||
|
final CompositeType compositeType,
|
||||||
|
final String lhsTableName,
|
||||||
|
final String[] lhsColumns) {
|
||||||
|
return new Iterable<AttributeDefinition>() {
|
||||||
|
@Override
|
||||||
|
public Iterator<AttributeDefinition> iterator() {
|
||||||
|
return new Iterator<AttributeDefinition>() {
|
||||||
|
private final int numberOfAttributes = compositeType.getSubtypes().length;
|
||||||
|
private int currentSubAttributeNumber = 0;
|
||||||
|
private int currentColumnPosition = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return currentSubAttributeNumber < numberOfAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeDefinition next() {
|
||||||
|
final int subAttributeNumber = currentSubAttributeNumber;
|
||||||
|
currentSubAttributeNumber++;
|
||||||
|
|
||||||
|
final String name = compositeType.getPropertyNames()[subAttributeNumber];
|
||||||
|
final Type type = compositeType.getSubtypes()[subAttributeNumber];
|
||||||
|
|
||||||
|
final int columnPosition = currentColumnPosition;
|
||||||
|
final int columnSpan = type.getColumnSpan( ownerEntityPersister.getFactory() );
|
||||||
|
final String[] subAttributeLhsColumns = ArrayHelper.slice( lhsColumns, columnPosition, columnSpan );
|
||||||
|
|
||||||
|
currentColumnPosition += columnSpan;
|
||||||
|
|
||||||
|
if ( type.isAssociationType() ) {
|
||||||
|
final AssociationType aType = (AssociationType) type;
|
||||||
|
return new AssociationAttributeDefinition() {
|
||||||
|
@Override
|
||||||
|
public AssociationKey getAssociationKey() {
|
||||||
|
/* TODO: is this always correct? */
|
||||||
|
//return new AssociationKey(
|
||||||
|
// joinable.getTableName(),
|
||||||
|
// JoinHelper.getRHSColumnNames( aType, getEntityPersister().getFactory() )
|
||||||
|
//);
|
||||||
|
return new AssociationKey(
|
||||||
|
lhsTableName,
|
||||||
|
subAttributeLhsColumns
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollection() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityDefinition toEntityDefinition() {
|
||||||
|
return (EntityPersister) aType.getAssociatedJoinable( ownerEntityPersister.getFactory() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionDefinition toCollectionDefinition() {
|
||||||
|
throw new WalkingException( "A collection cannot be mapped to a composite ID sub-attribute." );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
|
||||||
|
return new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CascadeStyle determineCascadeStyle() {
|
||||||
|
return CascadeStyles.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HydratedCompoundValueHandler getHydratedCompoundValueExtractor() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeSource getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if ( type.isComponentType() ) {
|
||||||
|
return new CompositionDefinition() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeSource getSource() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<AttributeDefinition> getAttributes() {
|
||||||
|
return CompositionSingularSubAttributesHelper.getSingularSubAttributes(
|
||||||
|
this,
|
||||||
|
ownerEntityPersister,
|
||||||
|
(CompositeType) type,
|
||||||
|
lhsTableName,
|
||||||
|
subAttributeLhsColumns
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new AttributeDefinition() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributeSource getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException( "Remove operation not supported here" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,37 +23,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.persister.walking.internal;
|
package org.hibernate.persister.walking.internal;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
|
||||||
import org.hibernate.engine.FetchStyle;
|
|
||||||
import org.hibernate.engine.FetchTiming;
|
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
|
||||||
import org.hibernate.engine.spi.CascadeStyles;
|
|
||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
|
||||||
import org.hibernate.loader.PropertyPath;
|
|
||||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
|
||||||
import org.hibernate.persister.entity.Joinable;
|
|
||||||
import org.hibernate.persister.spi.HydratedCompoundValueHandler;
|
|
||||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.AssociationKey;
|
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.AttributeSource;
|
import org.hibernate.persister.walking.spi.AttributeSource;
|
||||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EncapsulatedEntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EncapsulatedEntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.NonEncapsulatedEntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.NonEncapsulatedEntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.WalkingException;
|
|
||||||
import org.hibernate.type.AssociationType;
|
|
||||||
import org.hibernate.type.ComponentType;
|
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import static org.hibernate.engine.internal.JoinHelper.getLHSColumnNames;
|
|
||||||
import static org.hibernate.engine.internal.JoinHelper.getLHSTableName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
|
@ -78,12 +57,13 @@ public class EntityIdentifierDefinitionHelper {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityIdentifierDefinition buildEncapsulatedCompositeIdentifierDefinition(final AbstractEntityPersister entityPersister) {
|
public static EntityIdentifierDefinition buildEncapsulatedCompositeIdentifierDefinition(
|
||||||
|
final AbstractEntityPersister entityPersister) {
|
||||||
|
|
||||||
return new EncapsulatedEntityIdentifierDefinition() {
|
return new EncapsulatedEntityIdentifierDefinition() {
|
||||||
@Override
|
@Override
|
||||||
public AttributeDefinition getAttributeDefinition() {
|
public AttributeDefinition getAttributeDefinition() {
|
||||||
return new CompositeAttributeDefinitionAdapter( entityPersister );
|
return new CompositionDefinitionAdapter( entityPersister );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,7 +82,7 @@ public class EntityIdentifierDefinitionHelper {
|
||||||
return new NonEncapsulatedEntityIdentifierDefinition() {
|
return new NonEncapsulatedEntityIdentifierDefinition() {
|
||||||
@Override
|
@Override
|
||||||
public Iterable<AttributeDefinition> getAttributes() {
|
public Iterable<AttributeDefinition> getAttributes() {
|
||||||
return new CompositeAttributeDefinitionAdapter( entityPersister ).getAttributes();
|
return CompositionSingularSubAttributesHelper.getIdentifierSubAttributes( entityPersister );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,160 +134,20 @@ public class EntityIdentifierDefinitionHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CompositeAttributeDefinitionAdapter extends AttributeDefinitionAdapter implements CompositionDefinition {
|
private static class CompositionDefinitionAdapter extends AttributeDefinitionAdapter implements CompositionDefinition {
|
||||||
|
|
||||||
CompositeAttributeDefinitionAdapter(AbstractEntityPersister entityPersister) {
|
CompositionDefinitionAdapter(AbstractEntityPersister entityPersister) {
|
||||||
super( entityPersister );
|
super( entityPersister );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "<identifier-property:" + getName() + ">";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<AttributeDefinition> getAttributes() {
|
public Iterable<AttributeDefinition> getAttributes() {
|
||||||
return new Iterable<AttributeDefinition>() {
|
return CompositionSingularSubAttributesHelper.getIdentifierSubAttributes( getEntityPersister() );
|
||||||
@Override
|
|
||||||
public Iterator<AttributeDefinition> iterator() {
|
|
||||||
final ComponentType componentType = (ComponentType) getType();
|
|
||||||
return new Iterator<AttributeDefinition>() {
|
|
||||||
private final int numberOfAttributes = componentType.getSubtypes().length;
|
|
||||||
private int currentSubAttributeNumber = 0;
|
|
||||||
private int currentColumnPosition = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return currentSubAttributeNumber < numberOfAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AttributeDefinition next() {
|
|
||||||
final int subAttributeNumber = currentSubAttributeNumber;
|
|
||||||
currentSubAttributeNumber++;
|
|
||||||
|
|
||||||
final AttributeSource source = getSource();
|
|
||||||
final String name = componentType.getPropertyNames()[subAttributeNumber];
|
|
||||||
final Type type = componentType.getSubtypes()[subAttributeNumber];
|
|
||||||
|
|
||||||
final int columnPosition = currentColumnPosition;
|
|
||||||
currentColumnPosition += type.getColumnSpan( getEntityPersister().getFactory() );
|
|
||||||
|
|
||||||
if ( type.isAssociationType() ) {
|
|
||||||
final AssociationType aType = (AssociationType) type;
|
|
||||||
final Joinable joinable = aType.getAssociatedJoinable( getEntityPersister().getFactory() );
|
|
||||||
return new AssociationAttributeDefinition() {
|
|
||||||
@Override
|
|
||||||
public AssociationKey getAssociationKey() {
|
|
||||||
/* TODO: is this always correct? */
|
|
||||||
//return new AssociationKey(
|
|
||||||
// joinable.getTableName(),
|
|
||||||
// JoinHelper.getRHSColumnNames( aType, getEntityPersister().getFactory() )
|
|
||||||
//);
|
|
||||||
return new AssociationKey(
|
|
||||||
getEntityPersister().getTableName(),
|
|
||||||
getLHSColumnNames(
|
|
||||||
aType,
|
|
||||||
-1,
|
|
||||||
columnPosition,
|
|
||||||
getEntityPersister(),
|
|
||||||
getEntityPersister().getFactory()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCollection() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityDefinition toEntityDefinition() {
|
|
||||||
return (EntityPersister) joinable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionDefinition toCollectionDefinition() {
|
|
||||||
throw new WalkingException( "A collection cannot be mapped to a composite ID sub-attribute." );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
|
|
||||||
return new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CascadeStyle determineCascadeStyle() {
|
|
||||||
return CascadeStyles.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HydratedCompoundValueHandler getHydratedCompoundValueExtractor() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AttributeSource getSource() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if ( type.isComponentType() ) {
|
|
||||||
return new CompositionDefinition() {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AttributeSource getSource() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<AttributeDefinition> getAttributes() {
|
|
||||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new AttributeDefinition() {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AttributeSource getSource() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new UnsupportedOperationException( "Remove operation not supported here" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,6 +55,9 @@ public interface AssociationVisitationStrategy {
|
||||||
public void startingComposite(CompositionDefinition compositionDefinition);
|
public void startingComposite(CompositionDefinition compositionDefinition);
|
||||||
public void finishingComposite(CompositionDefinition compositionDefinition);
|
public void finishingComposite(CompositionDefinition compositionDefinition);
|
||||||
|
|
||||||
|
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition);
|
||||||
|
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition);
|
||||||
|
|
||||||
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
||||||
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,5 @@ public interface CollectionElementDefinition {
|
||||||
|
|
||||||
public EntityDefinition toEntityDefinition();
|
public EntityDefinition toEntityDefinition();
|
||||||
|
|
||||||
public CompositionDefinition toCompositeDefinition();
|
public CompositionElementDefinition toCompositeElementDefinition();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.persister.walking.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public interface CompositionElementDefinition extends CompositionDefinition{
|
||||||
|
public CollectionDefinition getCollectionDefinition();
|
||||||
|
}
|
|
@ -28,21 +28,12 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchStrategy;
|
|
||||||
import org.hibernate.engine.FetchStyle;
|
|
||||||
import org.hibernate.engine.FetchTiming;
|
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
|
||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Joinable;
|
|
||||||
import org.hibernate.persister.spi.HydratedCompoundValueHandler;
|
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides model graph visitation based on the defined metadata (as opposed to based on the incoming graph
|
* Provides model graph visitation based on the defined metadata (as opposed to based on the incoming graph
|
||||||
* as we see in cascade processing). In layman terms, we are walking the graph of the users model as defined by
|
* as we see in cascade processing). In layman terms, we are walking the graph of the users model as defined by
|
||||||
|
@ -211,7 +202,7 @@ public class MetadataDrivenModelGraphVisitor {
|
||||||
strategy.startingCollectionElements( elementDefinition );
|
strategy.startingCollectionElements( elementDefinition );
|
||||||
|
|
||||||
if ( elementDefinition.getType().isComponentType() ) {
|
if ( elementDefinition.getType().isComponentType() ) {
|
||||||
visitCompositeDefinition( elementDefinition.toCompositeDefinition() );
|
visitCompositeElementDefinition( elementDefinition.toCompositeElementDefinition() );
|
||||||
}
|
}
|
||||||
else if ( elementDefinition.getType().isEntityType() ) {
|
else if ( elementDefinition.getType().isEntityType() ) {
|
||||||
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
||||||
|
@ -220,6 +211,13 @@ public class MetadataDrivenModelGraphVisitor {
|
||||||
strategy.finishingCollectionElements( elementDefinition );
|
strategy.finishingCollectionElements( elementDefinition );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void visitCompositeElementDefinition(CompositionElementDefinition compositionElementDefinition) {
|
||||||
|
strategy.startingCompositeElement( compositionElementDefinition );
|
||||||
|
|
||||||
|
visitAttributes( compositionElementDefinition );
|
||||||
|
|
||||||
|
strategy.finishingCompositeElement( compositionElementDefinition );
|
||||||
|
}
|
||||||
|
|
||||||
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public abstract class AbstractCompositeBasedAttribute
|
||||||
private final int ownerAttributeNumber;
|
private final int ownerAttributeNumber;
|
||||||
|
|
||||||
public AbstractCompositeBasedAttribute(
|
public AbstractCompositeBasedAttribute(
|
||||||
AbstractCompositionDefinition source,
|
AbstractCompositionAttribute source,
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
int attributeNumber,
|
int attributeNumber,
|
||||||
String attributeName,
|
String attributeName,
|
||||||
|
@ -55,7 +55,7 @@ public abstract class AbstractCompositeBasedAttribute
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractCompositionDefinition getSource() {
|
public AbstractCompositionAttribute getSource() {
|
||||||
return (AbstractCompositionDefinition) super.getSource();
|
return (AbstractCompositionAttribute) super.getSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,9 @@ import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCompositionDefinition extends AbstractNonIdentifierAttribute implements
|
public abstract class AbstractCompositionAttribute extends AbstractNonIdentifierAttribute implements
|
||||||
CompositionDefinition {
|
CompositionDefinition {
|
||||||
protected AbstractCompositionDefinition(
|
protected AbstractCompositionAttribute(
|
||||||
AttributeSource source,
|
AttributeSource source,
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
int attributeNumber,
|
int attributeNumber,
|
||||||
|
@ -120,41 +120,41 @@ public abstract class AbstractCompositionDefinition extends AbstractNonIdentifie
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CompositeBasedAssociationAttribute(
|
return new CompositeBasedAssociationAttribute(
|
||||||
AbstractCompositionDefinition.this,
|
AbstractCompositionAttribute.this,
|
||||||
sessionFactory(),
|
sessionFactory(),
|
||||||
subAttributeNumber,
|
subAttributeNumber,
|
||||||
name,
|
name,
|
||||||
(AssociationType) type,
|
(AssociationType) type,
|
||||||
new BaselineAttributeInformation.Builder()
|
new BaselineAttributeInformation.Builder()
|
||||||
.setInsertable( AbstractCompositionDefinition.this.isInsertable() )
|
.setInsertable( AbstractCompositionAttribute.this.isInsertable() )
|
||||||
.setUpdateable( AbstractCompositionDefinition.this.isUpdateable() )
|
.setUpdateable( AbstractCompositionAttribute.this.isUpdateable() )
|
||||||
.setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() )
|
.setInsertGenerated( AbstractCompositionAttribute.this.isInsertGenerated() )
|
||||||
.setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() )
|
.setUpdateGenerated( AbstractCompositionAttribute.this.isUpdateGenerated() )
|
||||||
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
||||||
.setDirtyCheckable( true )
|
.setDirtyCheckable( true )
|
||||||
.setVersionable( AbstractCompositionDefinition.this.isVersionable() )
|
.setVersionable( AbstractCompositionAttribute.this.isVersionable() )
|
||||||
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
||||||
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
||||||
.createInformation(),
|
.createInformation(),
|
||||||
AbstractCompositionDefinition.this.attributeNumber(),
|
AbstractCompositionAttribute.this.attributeNumber(),
|
||||||
associationKey
|
associationKey
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ( type.isComponentType() ) {
|
else if ( type.isComponentType() ) {
|
||||||
return new CompositionBasedCompositionAttribute(
|
return new CompositionBasedCompositionAttribute(
|
||||||
AbstractCompositionDefinition.this,
|
AbstractCompositionAttribute.this,
|
||||||
sessionFactory(),
|
sessionFactory(),
|
||||||
subAttributeNumber,
|
subAttributeNumber,
|
||||||
name,
|
name,
|
||||||
(CompositeType) type,
|
(CompositeType) type,
|
||||||
new BaselineAttributeInformation.Builder()
|
new BaselineAttributeInformation.Builder()
|
||||||
.setInsertable( AbstractCompositionDefinition.this.isInsertable() )
|
.setInsertable( AbstractCompositionAttribute.this.isInsertable() )
|
||||||
.setUpdateable( AbstractCompositionDefinition.this.isUpdateable() )
|
.setUpdateable( AbstractCompositionAttribute.this.isUpdateable() )
|
||||||
.setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() )
|
.setInsertGenerated( AbstractCompositionAttribute.this.isInsertGenerated() )
|
||||||
.setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() )
|
.setUpdateGenerated( AbstractCompositionAttribute.this.isUpdateGenerated() )
|
||||||
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
||||||
.setDirtyCheckable( true )
|
.setDirtyCheckable( true )
|
||||||
.setVersionable( AbstractCompositionDefinition.this.isVersionable() )
|
.setVersionable( AbstractCompositionAttribute.this.isVersionable() )
|
||||||
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
||||||
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
||||||
.createInformation()
|
.createInformation()
|
||||||
|
@ -162,19 +162,19 @@ public abstract class AbstractCompositionDefinition extends AbstractNonIdentifie
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new CompositeBasedBasicAttribute(
|
return new CompositeBasedBasicAttribute(
|
||||||
AbstractCompositionDefinition.this,
|
AbstractCompositionAttribute.this,
|
||||||
sessionFactory(),
|
sessionFactory(),
|
||||||
subAttributeNumber,
|
subAttributeNumber,
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
new BaselineAttributeInformation.Builder()
|
new BaselineAttributeInformation.Builder()
|
||||||
.setInsertable( AbstractCompositionDefinition.this.isInsertable() )
|
.setInsertable( AbstractCompositionAttribute.this.isInsertable() )
|
||||||
.setUpdateable( AbstractCompositionDefinition.this.isUpdateable() )
|
.setUpdateable( AbstractCompositionAttribute.this.isUpdateable() )
|
||||||
.setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() )
|
.setInsertGenerated( AbstractCompositionAttribute.this.isInsertGenerated() )
|
||||||
.setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() )
|
.setUpdateGenerated( AbstractCompositionAttribute.this.isUpdateGenerated() )
|
||||||
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
.setNullable( getType().getPropertyNullability()[subAttributeNumber] )
|
||||||
.setDirtyCheckable( true )
|
.setDirtyCheckable( true )
|
||||||
.setVersionable( AbstractCompositionDefinition.this.isVersionable() )
|
.setVersionable( AbstractCompositionAttribute.this.isVersionable() )
|
||||||
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
.setCascadeStyle( getType().getCascadeStyle( subAttributeNumber ) )
|
||||||
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
.setFetchMode( getType().getFetchMode( subAttributeNumber ) )
|
||||||
.createInformation()
|
.createInformation()
|
||||||
|
@ -196,7 +196,7 @@ public abstract class AbstractCompositionDefinition extends AbstractNonIdentifie
|
||||||
return ( (EntityDefinition) getSource() ).getEntityPersister();
|
return ( (EntityDefinition) getSource() ).getEntityPersister();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return ( (AbstractCompositionDefinition) getSource() ).locateOwningPersister();
|
return ( (AbstractCompositionAttribute) getSource() ).locateOwningPersister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class CompositeBasedAssociationAttribute
|
||||||
private Joinable joinable;
|
private Joinable joinable;
|
||||||
|
|
||||||
public CompositeBasedAssociationAttribute(
|
public CompositeBasedAssociationAttribute(
|
||||||
AbstractCompositionDefinition source,
|
AbstractCompositionAttribute source,
|
||||||
SessionFactoryImplementor factory,
|
SessionFactoryImplementor factory,
|
||||||
int attributeNumber,
|
int attributeNumber,
|
||||||
String attributeName,
|
String attributeName,
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.hibernate.type.CompositeType;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CompositionBasedCompositionAttribute
|
public class CompositionBasedCompositionAttribute
|
||||||
extends AbstractCompositionDefinition
|
extends AbstractCompositionAttribute
|
||||||
implements CompositionDefinition {
|
implements CompositionDefinition {
|
||||||
public CompositionBasedCompositionAttribute(
|
public CompositionBasedCompositionAttribute(
|
||||||
CompositionDefinition source,
|
CompositionDefinition source,
|
||||||
|
|
|
@ -25,7 +25,7 @@ package org.hibernate.tuple.entity;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.tuple.component.AbstractCompositionDefinition;
|
import org.hibernate.tuple.component.AbstractCompositionAttribute;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
@ -34,7 +34,7 @@ import org.hibernate.type.CompositeType;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EntityBasedCompositionAttribute
|
public class EntityBasedCompositionAttribute
|
||||||
extends AbstractCompositionDefinition
|
extends AbstractCompositionAttribute
|
||||||
implements CompositionDefinition {
|
implements CompositionDefinition {
|
||||||
|
|
||||||
public EntityBasedCompositionAttribute(
|
public EntityBasedCompositionAttribute(
|
||||||
|
|
|
@ -42,6 +42,7 @@ import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ import org.hibernate.loader.spi.LoadQueryAliasResolutionContext;
|
||||||
import org.hibernate.loader.spi.NamedParameterContext;
|
import org.hibernate.loader.spi.NamedParameterContext;
|
||||||
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
|
import org.hibernate.loader.spi.NoOpLoadPlanAdvisor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.test.component.cascading.toone.PersonalInfo;
|
||||||
import org.hibernate.testing.FailureExpected;
|
import org.hibernate.testing.FailureExpected;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
import org.hibernate.testing.junit4.ExtraAssertions;
|
import org.hibernate.testing.junit4.ExtraAssertions;
|
||||||
|
@ -128,12 +130,15 @@ public class EncapsulatedCompositeAttributeResultSetProcessorTest extends BaseCo
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@Test
|
@Test
|
||||||
public void testNestedCompositeElementCollectionProcessing() throws Exception {
|
public void testNestedCompositeElementCollectionProcessing() throws Exception {
|
||||||
// create some test data
|
// create some test data
|
||||||
Session session = openSession();
|
Session session = openSession();
|
||||||
session.beginTransaction();
|
session.beginTransaction();
|
||||||
|
Person person = new Person();
|
||||||
|
person.id = 1;
|
||||||
|
person.name = "Joe Blow";
|
||||||
|
session.save( person );
|
||||||
Customer customer = new Customer();
|
Customer customer = new Customer();
|
||||||
customer.id = 1L;
|
customer.id = 1L;
|
||||||
Investment investment1 = new Investment();
|
Investment investment1 = new Investment();
|
||||||
|
@ -142,6 +147,7 @@ public class EncapsulatedCompositeAttributeResultSetProcessorTest extends BaseCo
|
||||||
investment1.monetaryAmount = new MonetaryAmount();
|
investment1.monetaryAmount = new MonetaryAmount();
|
||||||
investment1.monetaryAmount.currency = MonetaryAmount.CurrencyCode.USD;
|
investment1.monetaryAmount.currency = MonetaryAmount.CurrencyCode.USD;
|
||||||
investment1.monetaryAmount.amount = BigDecimal.valueOf( 1234, 2 );
|
investment1.monetaryAmount.amount = BigDecimal.valueOf( 1234, 2 );
|
||||||
|
investment1.performedBy = person;
|
||||||
Investment investment2 = new Investment();
|
Investment investment2 = new Investment();
|
||||||
investment2.description = "bond";
|
investment2.description = "bond";
|
||||||
investment2.date = new Date();
|
investment2.date = new Date();
|
||||||
|
@ -173,11 +179,11 @@ public class EncapsulatedCompositeAttributeResultSetProcessorTest extends BaseCo
|
||||||
// clean up test data
|
// clean up test data
|
||||||
session = openSession();
|
session = openSession();
|
||||||
session.beginTransaction();
|
session.beginTransaction();
|
||||||
session.createQuery( "delete Customer" ).executeUpdate();
|
session.delete( customerWork.investments.get( 0 ).performedBy );
|
||||||
|
session.delete( customerWork );
|
||||||
session.getTransaction().commit();
|
session.getTransaction().commit();
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
private List<?> getResults(EntityPersister entityPersister ) {
|
private List<?> getResults(EntityPersister entityPersister ) {
|
||||||
final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy(
|
final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy(
|
||||||
|
@ -288,6 +294,7 @@ public class EncapsulatedCompositeAttributeResultSetProcessorTest extends BaseCo
|
||||||
private MonetaryAmount monetaryAmount;
|
private MonetaryAmount monetaryAmount;
|
||||||
private String description;
|
private String description;
|
||||||
private Date date;
|
private Date date;
|
||||||
|
private Person performedBy;
|
||||||
|
|
||||||
@Embedded
|
@Embedded
|
||||||
public MonetaryAmount getMonetaryAmount() {
|
public MonetaryAmount getMonetaryAmount() {
|
||||||
|
@ -308,6 +315,13 @@ public class EncapsulatedCompositeAttributeResultSetProcessorTest extends BaseCo
|
||||||
public void setDate(Date date) {
|
public void setDate(Date date) {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
@ManyToOne
|
||||||
|
public Person getPerformedBy() {
|
||||||
|
return performedBy;
|
||||||
|
}
|
||||||
|
public void setPerformedBy(Person performedBy) {
|
||||||
|
this.performedBy = performedBy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Embeddable
|
@Embeddable
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||||
|
import org.hibernate.persister.walking.spi.CompositionElementDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
|
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
|
||||||
|
@ -168,6 +169,28 @@ public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startingCompositeElement(CompositionElementDefinition compositionElementDefinition) {
|
||||||
|
System.out.println(
|
||||||
|
String.format(
|
||||||
|
"%s Starting composite (%s)",
|
||||||
|
StringHelper.repeat( ">>", ++depth ),
|
||||||
|
compositionElementDefinition.toString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishingCompositeElement(CompositionElementDefinition compositionElementDefinition) {
|
||||||
|
System.out.println(
|
||||||
|
String.format(
|
||||||
|
"%s Finishing composite (%s)",
|
||||||
|
StringHelper.repeat( ">>", depth-- ),
|
||||||
|
compositionElementDefinition.toString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
|
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
|
||||||
System.out.println(
|
System.out.println(
|
||||||
|
|
Loading…
Reference in New Issue