use of org.hibernate.metamodel.mapping.CollectionPart in project hibernate-orm by hibernate.
the class ToOneAttributeMapping method createTableGroupJoin.
@Override
public TableGroupJoin createTableGroupJoin(NavigablePath navigablePath, TableGroup lhs, String explicitSourceAlias, SqlAstJoinType requestedJoinType, boolean fetched, boolean addsPredicate, SqlAliasBaseGenerator aliasBaseGenerator, SqlExpressionResolver sqlExpressionResolver, FromClauseAccess fromClauseAccess, SqlAstCreationContext creationContext) {
// This is vital for the map key property check that comes next
assert !(lhs instanceof PluralTableGroup);
TableGroup parentTableGroup = lhs;
ModelPartContainer parentContainer = lhs.getModelPart();
StringBuilder embeddablePathSb = null;
// Traverse up embeddable table groups until we find a table group for a collection part
while (!(parentContainer instanceof CollectionPart)) {
if (parentContainer instanceof EmbeddableValuedModelPart) {
if (embeddablePathSb == null) {
embeddablePathSb = new StringBuilder();
}
embeddablePathSb.insert(0, parentContainer.getPartName() + ".");
parentTableGroup = fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
parentContainer = parentTableGroup.getModelPart();
} else {
break;
}
}
final SqlAstJoinType joinType;
if (requestedJoinType == null) {
joinType = SqlAstJoinType.INNER;
} else {
joinType = requestedJoinType;
}
// we check if this attribute is the map key property to reuse the existing index table group
if (CollectionPart.Nature.ELEMENT.getName().equals(parentTableGroup.getNavigablePath().getUnaliasedLocalName()) && !addsPredicate && (joinType == SqlAstJoinType.INNER || joinType == SqlAstJoinType.LEFT)) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
final String indexPropertyName = pluralTableGroup.getModelPart().getIndexMetadata().getIndexPropertyName();
final String pathName;
if (embeddablePathSb != null) {
pathName = embeddablePathSb.append(getAttributeName()).toString();
} else {
pathName = getAttributeName();
}
if (pathName.equals(indexPropertyName)) {
final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup();
// If this is the map key property, we can reuse the index table group
initializeIfNeeded(lhs, requestedJoinType, indexTableGroup);
return new TableGroupJoin(navigablePath, joinType, new MappedByTableGroup(navigablePath, this, indexTableGroup, fetched, pluralTableGroup, (np, tableExpression) -> {
if (!canUseParentTableGroup) {
return false;
}
NavigablePath path = np.getParent();
// Fast path
if (path != null && navigablePath.equals(path)) {
return targetKeyPropertyNames.contains(np.getUnaliasedLocalName()) && identifyingColumnsTableExpression.equals(tableExpression);
}
final StringBuilder sb = new StringBuilder(np.getFullPath().length());
sb.append(np.getUnaliasedLocalName());
while (path != null && !navigablePath.equals(path)) {
sb.insert(0, '.');
sb.insert(0, path.getUnaliasedLocalName());
path = path.getParent();
}
return path != null && navigablePath.equals(path) && targetKeyPropertyNames.contains(sb.toString()) && identifyingColumnsTableExpression.equals(tableExpression);
}), null);
}
}
final LazyTableGroup lazyTableGroup = createRootTableGroupJoin(navigablePath, lhs, explicitSourceAlias, requestedJoinType, fetched, null, aliasBaseGenerator, sqlExpressionResolver, fromClauseAccess, creationContext);
final TableGroupJoin join = new TableGroupJoin(navigablePath, joinType, lazyTableGroup, null);
final TableReference lhsTableReference = lhs.resolveTableReference(navigablePath, identifyingColumnsTableExpression);
lazyTableGroup.setTableGroupInitializerCallback(tableGroup -> join.applyPredicate(foreignKeyDescriptor.generateJoinPredicate(sideNature == ForeignKeyDescriptor.Nature.TARGET ? lhsTableReference : tableGroup.getPrimaryTableReference(), sideNature == ForeignKeyDescriptor.Nature.TARGET ? tableGroup.getPrimaryTableReference() : lhsTableReference, sqlExpressionResolver, creationContext)));
return join;
}
use of org.hibernate.metamodel.mapping.CollectionPart in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretMapKey.
private static CollectionPart interpretMapKey(Collection bootValueMapping, CollectionPersister collectionDescriptor, String tableExpression, String sqlAliasStem, Dialect dialect, MappingModelCreationProcess creationProcess) {
assert bootValueMapping instanceof IndexedCollection;
final IndexedCollection indexedCollection = (IndexedCollection) bootValueMapping;
final Value bootMapKeyDescriptor = indexedCollection.getIndex();
if (bootMapKeyDescriptor instanceof BasicValue) {
final BasicValue basicValue = (BasicValue) bootMapKeyDescriptor;
final SelectableMapping selectableMapping = SelectableMappingImpl.from(tableExpression, basicValue.getSelectables().get(0), basicValue.resolve().getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
return new BasicValuedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, basicValue.resolve().getValueConverter(), selectableMapping);
}
if (bootMapKeyDescriptor instanceof Component) {
final Component component = (Component) bootMapKeyDescriptor;
final CompositeType compositeType = (CompositeType) component.getType();
final EmbeddableMappingTypeImpl mappingType = EmbeddableMappingTypeImpl.from(component, compositeType, inflightDescriptor -> new EmbeddedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, inflightDescriptor, // parent-injection
component.getParentProperty(), tableExpression, sqlAliasStem), creationProcess);
return (CollectionPart) mappingType.getEmbeddedValueMapping();
}
if (bootMapKeyDescriptor instanceof OneToMany || bootMapKeyDescriptor instanceof ToOne) {
final EntityType indexEntityType = (EntityType) collectionDescriptor.getIndexType();
final EntityPersister associatedEntity = creationProcess.getEntityPersister(indexEntityType.getAssociatedEntityName());
final EntityCollectionPart indexDescriptor = new EntityCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, bootMapKeyDescriptor, associatedEntity, creationProcess);
creationProcess.registerInitializationCallback("PluralAttributeMapping( " + bootValueMapping.getRole() + ") - index descriptor", () -> {
indexDescriptor.finishInitialization(collectionDescriptor, bootValueMapping, indexEntityType.getRHSUniqueKeyPropertyName(), creationProcess);
return true;
});
return indexDescriptor;
}
throw new NotYetImplementedFor6Exception("Support for plural attributes with index type [" + bootMapKeyDescriptor + "] not yet implemented");
}
use of org.hibernate.metamodel.mapping.CollectionPart in project hibernate-orm by hibernate.
the class StandardEntityGraphTraversalStateImpl method traverse.
@Override
public TraversalResult traverse(FetchParent fetchParent, Fetchable fetchable, boolean exploreKeySubgraph) {
assert !(fetchable instanceof CollectionPart);
final GraphImplementor previousContextRoot = currentGraphContext;
AttributeNodeImplementor attributeNode = null;
if (appliesTo(fetchParent)) {
attributeNode = currentGraphContext.findAttributeNode(fetchable.getFetchableName());
}
currentGraphContext = null;
FetchTiming fetchTiming = null;
boolean joined = false;
if (attributeNode != null) {
fetchTiming = FetchTiming.IMMEDIATE;
joined = true;
final Map<Class<?>, SubGraphImplementor> subgraphMap;
final Class<?> subgraphMapKey;
if (fetchable instanceof PluralAttributeMapping) {
PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable;
assert exploreKeySubgraph && isJpaMapCollectionType(pluralAttributeMapping) || !exploreKeySubgraph && !isJpaMapCollectionType(pluralAttributeMapping);
if (exploreKeySubgraph) {
subgraphMap = attributeNode.getKeySubGraphMap();
subgraphMapKey = getEntityCollectionPartJavaClass(pluralAttributeMapping.getIndexDescriptor());
} else {
subgraphMap = attributeNode.getSubGraphMap();
subgraphMapKey = getEntityCollectionPartJavaClass(pluralAttributeMapping.getElementDescriptor());
}
} else {
assert !exploreKeySubgraph;
subgraphMap = attributeNode.getSubGraphMap();
subgraphMapKey = fetchable.getJavaType().getJavaTypeClass();
}
if (subgraphMap != null && subgraphMapKey != null) {
currentGraphContext = subgraphMap.get(subgraphMapKey);
}
}
if (fetchTiming == null) {
if (graphSemantic == GraphSemantic.FETCH) {
fetchTiming = FetchTiming.DELAYED;
joined = false;
} else {
fetchTiming = fetchable.getMappedFetchOptions().getTiming();
joined = fetchable.getMappedFetchOptions().getStyle() == FetchStyle.JOIN;
}
}
return new TraversalResult(previousContextRoot, fetchTiming, joined);
}
use of org.hibernate.metamodel.mapping.CollectionPart in project hibernate-orm by hibernate.
the class PluralAttributePath method resolvePathPart.
@Override
public DomainPath resolvePathPart(String name, String identifier, boolean isTerminal, TranslationContext translationContext) {
final ModelPart subPart = pluralAttributeMapping.findSubPart(name, null);
if (subPart != null) {
if (subPart instanceof CollectionPart) {
return new CollectionPartPath(this, (CollectionPart) subPart);
}
if (subPart instanceof EmbeddableValuedModelPart) {
return new DomainPathContinuation(navigablePath.append(name), this, subPart);
}
if (subPart instanceof ToOneAttributeMapping) {
return new FkDomainPathContinuation(navigablePath.append(name), this, (ToOneAttributeMapping) subPart);
}
// leaf case:
final CollectionPartPath elementPath = new CollectionPartPath(this, pluralAttributeMapping.getElementDescriptor());
return (DomainPath) elementPath.resolvePathPart(name, identifier, isTerminal, translationContext);
}
if (pluralAttributeMapping.getElementDescriptor() instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart elementDescriptor = (EmbeddableValuedModelPart) pluralAttributeMapping.getElementDescriptor();
final ModelPart elementSubPart = elementDescriptor.findSubPart(name, null);
if (elementSubPart != null) {
// create the CollectionSubPath to use as the `lhs` for the element sub-path
final CollectionPartPath elementPath = new CollectionPartPath(this, (CollectionPart) elementDescriptor);
return new DomainPathContinuation(elementPath.getNavigablePath().append(name), this, elementSubPart);
}
}
if (pluralAttributeMapping.getIndexDescriptor() instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart indexDescriptor = (EmbeddableValuedModelPart) pluralAttributeMapping.getIndexDescriptor();
final ModelPart indexSubPart = indexDescriptor.findSubPart(name, null);
if (indexSubPart != null) {
// create the CollectionSubPath to use as the `lhs` for the element sub-path
final CollectionPartPath indexPath = new CollectionPartPath(this, (CollectionPart) indexDescriptor);
return new DomainPathContinuation(indexPath.getNavigablePath().append(name), this, indexSubPart);
}
}
return null;
}
use of org.hibernate.metamodel.mapping.CollectionPart in project hibernate-orm by hibernate.
the class SqmMappingModelHelper method resolveSqmPath.
private static ModelPart resolveSqmPath(SqmPath<?> sqmPath, MappingMetamodel domainModel, Function<NavigablePath, TableGroup> tableGroupLocator) {
if (sqmPath instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath;
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
return domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
}
// see if the LHS is treated
if (sqmPath.getLhs() instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath.getLhs();
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
final EntityPersister container = domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
return container.findSubPart(sqmPath.getNavigablePath().getLocalName(), container);
}
// Plural path parts are not joined and thus also have no table group
if (sqmPath instanceof AbstractSqmSpecificPluralPartPath<?>) {
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getLhs().getNavigablePath());
final ModelPartContainer pluralPart = (ModelPartContainer) lhsTableGroup.getModelPart().findSubPart(sqmPath.getLhs().getReferencedPathSource().getPathName(), null);
final CollectionPart collectionPart = (CollectionPart) pluralPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
// as that is the mapping type of the expression
if (collectionPart instanceof EntityCollectionPart) {
return ((EntityCollectionPart) collectionPart).getEntityMappingType();
}
return collectionPart;
}
if (sqmPath.getLhs() == null) {
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) sqmPath.getReferencedPathSource();
return domainModel.findEntityDescriptor(entityDomainType.getHibernateEntityName());
}
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getNavigablePath());
final ModelPartContainer modelPart;
if (lhsTableGroup == null) {
modelPart = (ModelPartContainer) resolveSqmPath(sqmPath.getLhs(), domainModel, tableGroupLocator);
} else {
modelPart = lhsTableGroup.getModelPart();
}
return modelPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
}
Aggregations