use of org.hibernate.metamodel.mapping.BasicValuedModelPart in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretPluralAttributeMappingKeyDescriptor.
private static void interpretPluralAttributeMappingKeyDescriptor(PluralAttributeMappingImpl attributeMapping, Collection bootValueMapping, CollectionPersister collectionDescriptor, ManagedMappingType declaringType, Dialect dialect, MappingModelCreationProcess creationProcess) {
ModelPart attributeMappingSubPart = null;
if (!StringHelper.isEmpty(collectionDescriptor.getMappedByProperty())) {
attributeMappingSubPart = ((ModelPartContainer) attributeMapping.getElementDescriptor().getPartMappingType()).findSubPart(collectionDescriptor.getMappedByProperty(), null);
}
if (attributeMappingSubPart instanceof ToOneAttributeMapping) {
final ToOneAttributeMapping referencedAttributeMapping = (ToOneAttributeMapping) attributeMappingSubPart;
setReferencedAttributeForeignKeyDescriptor(attributeMapping, referencedAttributeMapping, referencedAttributeMapping.findContainingEntityMapping().getEntityPersister(), collectionDescriptor.getMappedByProperty(), dialect, creationProcess);
return;
}
final KeyValue bootValueMappingKey = bootValueMapping.getKey();
final Type keyType = bootValueMappingKey.getType();
final ModelPart fkTarget;
final String lhsPropertyName = collectionDescriptor.getCollectionType().getLHSPropertyName();
final boolean isReferenceToPrimaryKey = lhsPropertyName == null;
final ManagedMappingType keyDeclaringType;
if (collectionDescriptor.getElementType().isEntityType()) {
keyDeclaringType = ((QueryableCollection) collectionDescriptor).getElementPersister();
} else {
// This is not "really correct" but it is as good as it gets.
// The key declaring type serves as declaring type for the inverse model part of a FK.
// Most of the time, there is a proper managed type, but not for basic collections.
// Since the declaring type is needed for certain operations, we use the one from the target side of the FK
keyDeclaringType = declaringType;
}
if (isReferenceToPrimaryKey) {
fkTarget = collectionDescriptor.getOwnerEntityPersister().getIdentifierMapping();
} else {
fkTarget = declaringType.findAttributeMapping(lhsPropertyName);
}
if (keyType instanceof BasicType) {
assert bootValueMappingKey.getColumnSpan() == 1;
assert fkTarget instanceof BasicValuedModelPart;
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final String tableExpression = getTableIdentifierExpression(bootValueMappingKey.getTable(), creationProcess);
final SelectableMapping keySelectableMapping = SelectableMappingImpl.from(tableExpression, bootValueMappingKey.getSelectables().get(0), (JdbcMapping) keyType, dialect, creationProcess.getSqmFunctionRegistry());
attributeMapping.setForeignKeyDescriptor(new SimpleForeignKeyDescriptor(keyDeclaringType, simpleFkTarget, null, keySelectableMapping, simpleFkTarget, isReferenceToPrimaryKey, ((SimpleValue) bootValueMappingKey).isConstrained()));
} else if (fkTarget instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) fkTarget, bootValueMapping, keyDeclaringType, collectionDescriptor.getAttributeMapping(), false, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else {
throw new NotYetImplementedFor6Exception("Support for " + fkTarget.getClass() + " foreign keys not yet implemented: " + bootValueMapping.getRole());
}
}
use of org.hibernate.metamodel.mapping.BasicValuedModelPart in project hibernate-orm by hibernate.
the class DiscriminatedAssociationMapping method from.
public static DiscriminatedAssociationMapping from(NavigableRole containerRole, JavaType<?> baseAssociationJtd, DiscriminatedAssociationModelPart declaringModelPart, AnyType anyType, Any bootValueMapping, MappingModelCreationProcess creationProcess) {
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final Dialect dialect = sessionFactory.getSqlStringGenerationContext().getDialect();
final String tableName = MappingModelCreationHelper.getTableIdentifierExpression(bootValueMapping.getTable(), creationProcess);
assert bootValueMapping.getColumnSpan() == 2;
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
assert columnIterator.hasNext();
final Selectable metaSelectable = columnIterator.next();
assert columnIterator.hasNext();
final Selectable keySelectable = columnIterator.next();
assert !columnIterator.hasNext();
assert !metaSelectable.isFormula();
assert !keySelectable.isFormula();
final Column metaColumn = (Column) metaSelectable;
final Column keyColumn = (Column) keySelectable;
final AnyDiscriminatorPart discriminatorPart = new AnyDiscriminatorPart(containerRole.append(AnyDiscriminatorPart.ROLE_NAME), declaringModelPart, tableName, metaColumn.getText(dialect), metaColumn.getSqlType(), metaColumn.getLength(), metaColumn.getPrecision(), metaColumn.getScale(), bootValueMapping.isNullable(), (MetaType) anyType.getDiscriminatorType());
final BasicType<?> keyType = (BasicType<?>) anyType.getIdentifierType();
final BasicValuedModelPart keyPart = new AnyKeyPart(containerRole.append(AnyKeyPart.ROLE_NAME), declaringModelPart, tableName, keyColumn.getText(dialect), keyColumn.getSqlType(), keyColumn.getLength(), keyColumn.getPrecision(), keyColumn.getScale(), bootValueMapping.isNullable(), keyType);
return new DiscriminatedAssociationMapping(declaringModelPart, discriminatorPart, keyPart, baseAssociationJtd, bootValueMapping.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE, bootValueMapping.getMetaValues(), sessionFactory);
}
use of org.hibernate.metamodel.mapping.BasicValuedModelPart in project hibernate-orm by hibernate.
the class AbstractDomainPath method addSortSpecification.
private void addSortSpecification(EmbeddableValuedModelPart embeddableValuedModelPart, QuerySpec ast, TableGroup tableGroup, String collation, String modelPartName, SortOrder sortOrder, NullPrecedence nullPrecedence, SqlAstCreationState creationState) {
if (embeddableValuedModelPart.getFetchableName().equals(modelPartName) || ELEMENT_TOKEN.equals(modelPartName)) {
embeddableValuedModelPart.forEachSelectable((columnIndex, selection) -> {
addSortSpecification(selection, ast, tableGroup, collation, sortOrder, nullPrecedence, creationState);
});
} else {
ModelPart subPart = embeddableValuedModelPart.findSubPart(modelPartName, null);
assert subPart instanceof BasicValuedModelPart;
addSortSpecification((BasicValuedModelPart) subPart, ast, tableGroup, collation, sortOrder, nullPrecedence, creationState);
}
}
use of org.hibernate.metamodel.mapping.BasicValuedModelPart in project hibernate-orm by hibernate.
the class InPredicateRestrictionProducer method produceRestriction.
@Override
public InListPredicate produceRestriction(List<?> matchingIdValues, EntityMappingType entityDescriptor, int valueIndex, ModelPart valueModelPart, TableReference mutatingTableReference, Supplier<Consumer<SelectableConsumer>> columnsToMatchVisitationSupplier, ExecutionContext executionContext) {
assert matchingIdValues != null;
assert !matchingIdValues.isEmpty();
final SessionFactoryImplementor sessionFactory = executionContext.getSession().getFactory();
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final int idColumnCount = identifierMapping.getJdbcTypeCount();
assert idColumnCount > 0;
final InListPredicate predicate;
if (idColumnCount == 1) {
final BasicValuedModelPart basicIdMapping = (BasicValuedModelPart) identifierMapping;
final String idColumn = basicIdMapping.getSelectionExpression();
final Expression inFixture = new ColumnReference(mutatingTableReference, idColumn, // id columns cannot be formulas and cannot have custom read and write expressions
false, null, null, basicIdMapping.getJdbcMapping(), sessionFactory);
predicate = new InListPredicate(inFixture);
matchingIdValues.forEach(matchingId -> predicate.addExpression(new JdbcLiteral<>(matchingId, basicIdMapping.getJdbcMapping())));
} else {
final List<ColumnReference> columnReferences = new ArrayList<>(idColumnCount);
final List<JdbcMapping> jdbcMappings = new ArrayList<>(idColumnCount);
identifierMapping.forEachSelectable((columnIndex, selection) -> {
columnReferences.add(new ColumnReference(mutatingTableReference, selection, sessionFactory));
jdbcMappings.add(selection.getJdbcMapping());
});
final Expression inFixture = new SqlTuple(columnReferences, identifierMapping);
predicate = new InListPredicate(inFixture);
matchingIdValues.forEach(matchingId -> {
assert matchingId instanceof Object[];
final Object[] matchingIdParts = (Object[]) matchingId;
final List<JdbcLiteral<?>> tupleParts = new ArrayList<>(idColumnCount);
for (int p = 0; p < matchingIdParts.length; p++) {
tupleParts.add(new JdbcLiteral<>(matchingIdParts[p], jdbcMappings.get(p)));
}
predicate.addExpression(new SqlTuple(tupleParts, identifierMapping));
});
}
return predicate;
}
use of org.hibernate.metamodel.mapping.BasicValuedModelPart in project hibernate-orm by hibernate.
the class AbstractEntityPersister method selectFragment.
@Override
public String selectFragment(String alias, String suffix) {
final QuerySpec rootQuerySpec = new QuerySpec(true);
final String rootTableName = getRootTableName();
final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), LockOptions.NONE, (fetchParent, querySpec, creationState) -> {
final List<Fetch> fetches = new ArrayList<>();
fetchParent.getReferencedMappingContainer().visitFetchables(fetchable -> {
// Ignore plural attributes
if (fetchable instanceof PluralAttributeMapping) {
return;
}
FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
final boolean selectable;
if (fetchable instanceof StateArrayContributorMapping) {
final int propertyNumber = ((StateArrayContributorMapping) fetchable).getStateArrayPosition();
final int tableNumber = getSubclassPropertyTableNumber(propertyNumber);
selectable = !isSubclassTableSequentialSelect(tableNumber) && propertySelectable[propertyNumber];
} else {
selectable = true;
}
if (fetchable instanceof BasicValuedModelPart) {
// Ignore lazy basic columns
if (fetchTiming == FetchTiming.DELAYED) {
return;
}
} else if (fetchable instanceof Association) {
final Association association = (Association) fetchable;
// Ignore the fetchable if the FK is on the other side
if (association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET) {
return;
}
// Ensure the FK comes from the root table
if (!rootTableName.equals(association.getForeignKeyDescriptor().getKeyTable())) {
return;
}
fetchTiming = FetchTiming.DELAYED;
}
if (selectable) {
final NavigablePath navigablePath = fetchParent.resolveNavigablePath(fetchable);
final Fetch fetch = fetchParent.generateFetchableFetch(fetchable, navigablePath, fetchTiming, true, null, creationState);
fetches.add(fetch);
}
}, null);
return fetches;
}, true, getFactory());
final NavigablePath entityPath = new NavigablePath(getRootPathName());
final TableGroup rootTableGroup = createRootTableGroup(true, entityPath, null, () -> p -> {
}, new SqlAliasBaseConstant(alias), sqlAstCreationState.getSqlExpressionResolver(), sqlAstCreationState.getFromClauseAccess(), getFactory());
rootQuerySpec.getFromClause().addRoot(rootTableGroup);
sqlAstCreationState.getFromClauseAccess().registerTableGroup(entityPath, rootTableGroup);
createDomainResult(entityPath, rootTableGroup, null, sqlAstCreationState);
// Wrap expressions with aliases
final SelectClause selectClause = rootQuerySpec.getSelectClause();
final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
int i = 0;
for (String identifierAlias : identifierAliases) {
sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), identifierAlias + suffix)));
i++;
}
if (entityMetamodel.hasSubclasses()) {
sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), getDiscriminatorAlias() + suffix)));
i++;
}
if (hasRowId()) {
sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), ROWID_ALIAS + suffix)));
i++;
}
final String[] columnAliases = getSubclassColumnAliasClosure();
final String[] formulaAliases = getSubclassFormulaAliasClosure();
int columnIndex = 0;
int formulaIndex = 0;
for (; i < sqlSelections.size(); i++) {
final SqlSelection sqlSelection = sqlSelections.get(i);
final ColumnReference columnReference = (ColumnReference) sqlSelection.getExpression();
final String selectAlias;
if (!columnReference.isColumnExpressionFormula()) {
// Skip over columns that are not selectable like in the fetch generation
while (!subclassColumnSelectableClosure[columnIndex]) {
columnIndex++;
}
selectAlias = columnAliases[columnIndex++] + suffix;
} else {
selectAlias = formulaAliases[formulaIndex++] + suffix;
}
sqlSelections.set(i, new SqlSelectionImpl(sqlSelection.getValuesArrayPosition(), sqlSelection.getJdbcResultSetIndex(), new AliasedExpression(sqlSelection.getExpression(), selectAlias)));
}
final String sql = getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory().buildSelectTranslator(getFactory(), new SelectStatement(rootQuerySpec)).translate(null, QueryOptions.NONE).getSql();
final int fromIndex = sql.lastIndexOf(" from");
final String expression;
if (fromIndex != -1) {
expression = sql.substring("select ".length(), fromIndex);
} else {
expression = sql.substring("select ".length());
}
return expression;
}
Aggregations