org.hibernate.loader.plan.build.internal.returns.AbstractCollectionReference Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.loader.plan.build.internal.returns;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.plan.build.internal.spaces.CompositePropertyMapping;
import org.hibernate.loader.plan.build.internal.spaces.QuerySpaceHelper;
import org.hibernate.loader.plan.build.spi.ExpandingCollectionQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan.spi.CollectionFetchableElement;
import org.hibernate.loader.plan.spi.CollectionFetchableIndex;
import org.hibernate.loader.plan.spi.CollectionReference;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.CollectionPropertyNames;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/**
* @author Steve Ebersole
*/
public abstract class AbstractCollectionReference implements CollectionReference {
private final ExpandingCollectionQuerySpace collectionQuerySpace;
private final PropertyPath propertyPath;
private final CollectionFetchableIndex index;
private final CollectionFetchableElement element;
private final boolean allowElementJoin;
private final boolean allowIndexJoin;
protected AbstractCollectionReference(
ExpandingCollectionQuerySpace collectionQuerySpace,
PropertyPath propertyPath,
boolean shouldIncludeJoins) {
this.collectionQuerySpace = collectionQuerySpace;
this.propertyPath = propertyPath;
this.allowElementJoin = shouldIncludeJoins;
// Currently we can only allow a join for the collection index if all of the following are true:
// - collection element joins are allowed;
// - index is an EntityType;
// - index values are not "formulas" (e.g., a @MapKey index is translated into "formula" value(s)).
// Hibernate cannot currently support eager joining of associations within a component (@Embeddable) as an index.
if ( shouldIncludeJoins &&
collectionQuerySpace.getCollectionPersister().hasIndex() &&
collectionQuerySpace.getCollectionPersister().getIndexType().isEntityType() ) {
final String[] indexFormulas =
( (QueryableCollection) collectionQuerySpace.getCollectionPersister() ).getIndexFormulas();
final int nNonNullFormulas = ArrayHelper.countNonNull( indexFormulas );
this.allowIndexJoin = nNonNullFormulas == 0;
}
else {
this.allowIndexJoin = false;
}
// All other fields must be initialized before building this.index and this.element.
this.index = buildIndexGraph();
this.element = buildElementGraph();
}
private CollectionFetchableIndex buildIndexGraph() {
final CollectionPersister persister = collectionQuerySpace.getCollectionPersister();
if ( persister.hasIndex() ) {
final Type type = persister.getIndexType();
if ( type.isAssociationType() ) {
if ( type.isEntityType() ) {
final EntityPersister indexPersister = persister.getFactory().getEntityPersister(
( (EntityType) type ).getAssociatedEntityName()
);
final ExpandingEntityQuerySpace entityQuerySpace = QuerySpaceHelper.INSTANCE.makeEntityQuerySpace(
collectionQuerySpace,
indexPersister,
CollectionPropertyNames.COLLECTION_INDICES,
(EntityType) persister.getIndexType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowIndexJoin
);
return new CollectionFetchableIndexEntityGraph( this, entityQuerySpace );
}
else if ( type.isAnyType() ) {
return new CollectionFetchableIndexAnyGraph( this );
}
}
else if ( type.isComponentType() ) {
final ExpandingCompositeQuerySpace compositeQuerySpace = QuerySpaceHelper.INSTANCE.makeCompositeQuerySpace(
collectionQuerySpace,
new CompositePropertyMapping(
(CompositeType) persister.getIndexType(),
(PropertyMapping) persister,
""
),
CollectionPropertyNames.COLLECTION_INDICES,
(CompositeType) persister.getIndexType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowIndexJoin
);
return new CollectionFetchableIndexCompositeGraph( this, compositeQuerySpace );
}
}
return null;
}
private CollectionFetchableElement buildElementGraph() {
final CollectionPersister persister = collectionQuerySpace.getCollectionPersister();
final Type type = persister.getElementType();
if ( type.isAssociationType() ) {
if ( type.isEntityType() ) {
final EntityPersister elementPersister = persister.getFactory().getEntityPersister(
( (EntityType) type ).getAssociatedEntityName()
);
final ExpandingEntityQuerySpace entityQuerySpace = QuerySpaceHelper.INSTANCE.makeEntityQuerySpace(
collectionQuerySpace,
elementPersister,
CollectionPropertyNames.COLLECTION_ELEMENTS,
(EntityType) persister.getElementType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowElementJoin
);
return new CollectionFetchableElementEntityGraph( this, entityQuerySpace );
}
else if ( type.isAnyType() ) {
return new CollectionFetchableElementAnyGraph( this );
}
}
else if ( type.isComponentType() ) {
final ExpandingCompositeQuerySpace compositeQuerySpace = QuerySpaceHelper.INSTANCE.makeCompositeQuerySpace(
collectionQuerySpace,
new CompositePropertyMapping(
(CompositeType) persister.getElementType(),
(PropertyMapping) persister,
""
),
CollectionPropertyNames.COLLECTION_ELEMENTS,
(CompositeType) persister.getElementType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowElementJoin
);
return new CollectionFetchableElementCompositeGraph( this, compositeQuerySpace );
}
return null;
}
@Override
public boolean allowElementJoin() {
return allowElementJoin;
}
@Override
public boolean allowIndexJoin() {
return allowIndexJoin;
}
@Override
public String getQuerySpaceUid() {
return collectionQuerySpace.getUid();
}
@Override
public CollectionPersister getCollectionPersister() {
return collectionQuerySpace.getCollectionPersister();
}
@Override
public CollectionFetchableIndex getIndexGraph() {
return index;
}
@Override
public CollectionFetchableElement getElementGraph() {
return element;
}
@Override
public PropertyPath getPropertyPath() {
return propertyPath;
}
}