use of org.hibernate.metamodel.mapping.EntityDiscriminatorMapping in project hibernate-orm by hibernate.
the class EntityValuedPathInterpretation method from.
public static <T> EntityValuedPathInterpretation<T> from(NavigablePath navigablePath, TableGroup tableGroup, ModelPart resultModelPart, EntityValuedModelPart mapping, EntityValuedModelPart treatedMapping, SqmToSqlAstConverter sqlAstCreationState) {
final SqlExpressionResolver sqlExprResolver = sqlAstCreationState.getSqlExpressionResolver();
final SessionFactoryImplementor sessionFactory = sqlAstCreationState.getCreationContext().getSessionFactory();
final Expression sqlExpression;
if (resultModelPart == null) {
final EntityMappingType entityMappingType = mapping.getEntityMappingType();
final EntityIdentifierMapping identifierMapping = entityMappingType.getIdentifierMapping();
final EntityDiscriminatorMapping discriminatorMapping = entityMappingType.getDiscriminatorMapping();
final List<Expression> expressions = new ArrayList<>(entityMappingType.getJdbcTypeCount() + identifierMapping.getJdbcTypeCount() + (discriminatorMapping == null ? 0 : 1));
final TableGroup parentTableGroup = tableGroup;
final SelectableConsumer selectableConsumer = (selectionIndex, selectableMapping) -> {
final TableReference tableReference = parentTableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression(), false);
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
};
identifierMapping.forEachSelectable(selectableConsumer);
if (discriminatorMapping != null) {
discriminatorMapping.forEachSelectable(selectableConsumer);
}
entityMappingType.forEachSelectable(selectableConsumer);
sqlExpression = new SqlTuple(expressions, entityMappingType);
} else {
if (resultModelPart instanceof BasicValuedModelPart) {
final BasicValuedModelPart basicValuedModelPart = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, basicValuedModelPart.getContainingTableExpression());
sqlExpression = sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, basicValuedModelPart.getSelectionExpression()), processingState -> new ColumnReference(tableReference, basicValuedModelPart, sessionFactory));
} else {
final List<Expression> expressions = new ArrayList<>(resultModelPart.getJdbcTypeCount());
resultModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression());
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
});
sqlExpression = new SqlTuple(expressions, resultModelPart);
}
}
return new EntityValuedPathInterpretation<>(sqlExpression, navigablePath, tableGroup, treatedMapping);
}
use of org.hibernate.metamodel.mapping.EntityDiscriminatorMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInsertionTargetPaths.
public AdditionalInsertValues visitInsertionTargetPaths(BiConsumer<Assignable, List<ColumnReference>> targetColumnReferenceConsumer, SqmInsertStatement<?> sqmStatement, EntityPersister entityDescriptor, TableGroup rootTableGroup) {
final List<SqmPath<?>> targetPaths = sqmStatement.getInsertionTargetPaths();
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
IdentifierGenerator identifierGenerator = entityDescriptor.getIdentifierGenerator();
Expression versionExpression = null;
Expression discriminatorExpression = null;
BasicEntityIdentifierMapping identifierMapping = null;
// We use the id property name to null the identifier generator variable if the target paths contain the id
final String identifierPropertyName;
if (identifierGenerator != null) {
identifierPropertyName = entityDescriptor.getIdentifierPropertyName();
} else {
identifierPropertyName = null;
}
final String versionAttributeName;
boolean needsVersionInsert;
if (entityDescriptor.isVersioned()) {
versionAttributeName = entityDescriptor.getVersionMapping().getVersionAttribute().getAttributeName();
needsVersionInsert = true;
} else {
versionAttributeName = null;
needsVersionInsert = false;
}
// Go through all target paths and remember if the target paths contain the version or id attributes
for (int i = 0; i < targetPaths.size(); i++) {
final SqmPath<?> path = targetPaths.get(i);
final String localName = path.getNavigablePath().getLocalName();
if (localName.equals(identifierPropertyName)) {
identifierGenerator = null;
} else if (localName.equals(versionAttributeName)) {
needsVersionInsert = false;
}
final Assignable assignable = (Assignable) path.accept(this);
targetColumnReferenceConsumer.accept(assignable, assignable.getColumnReferences());
}
if (needsVersionInsert) {
final BasicValuedPathInterpretation<?> versionPath = BasicValuedPathInterpretation.from((SqmBasicValuedSimplePath<?>) sqmStatement.getTarget().get(versionAttributeName), this, this, jpaQueryComplianceEnabled);
final List<ColumnReference> targetColumnReferences = versionPath.getColumnReferences();
assert targetColumnReferences.size() == 1;
targetColumnReferenceConsumer.accept(versionPath, targetColumnReferences);
versionExpression = new VersionTypeSeedParameterSpecification(entityDescriptor.getVersionMapping().getJdbcMapping(), entityDescriptor.getVersionJavaType());
}
if (discriminatorMapping != null && discriminatorMapping.isPhysical()) {
final BasicValuedPathInterpretation<?> discriminatorPath = new BasicValuedPathInterpretation<>(new ColumnReference(rootTableGroup.resolveTableReference(discriminatorMapping.getContainingTableExpression()), discriminatorMapping, getCreationContext().getSessionFactory()), rootTableGroup.getNavigablePath().append(discriminatorMapping.getPartName()), discriminatorMapping, rootTableGroup);
targetColumnReferenceConsumer.accept(discriminatorPath, discriminatorPath.getColumnReferences());
discriminatorExpression = new QueryLiteral<>(entityDescriptor.getDiscriminatorValue(), discriminatorMapping);
}
// This uses identity generation, so we don't need to list the column
if (identifierGenerator instanceof PostInsertIdentifierGenerator || identifierGenerator instanceof CompositeNestedGeneratedValueGenerator) {
identifierGenerator = null;
} else if (identifierGenerator != null) {
identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
final BasicValuedPathInterpretation<?> identifierPath = new BasicValuedPathInterpretation<>(new ColumnReference(rootTableGroup.resolveTableReference(identifierMapping.getContainingTableExpression()), identifierMapping, getCreationContext().getSessionFactory()), rootTableGroup.getNavigablePath().append(identifierMapping.getPartName()), identifierMapping, rootTableGroup);
targetColumnReferenceConsumer.accept(identifierPath, identifierPath.getColumnReferences());
}
return new AdditionalInsertValues(versionExpression, discriminatorExpression, identifierGenerator, identifierMapping);
}
use of org.hibernate.metamodel.mapping.EntityDiscriminatorMapping in project hibernate-orm by hibernate.
the class TemporaryTable method createEntityTable.
public static TemporaryTable createEntityTable(EntityMappingType entityDescriptor, Function<String, String> temporaryTableNameAdjuster, Dialect dialect, RuntimeModelCreationContext runtimeModelCreationContext) {
return new TemporaryTable(entityDescriptor, temporaryTableNameAdjuster, dialect, temporaryTable -> {
final List<TemporaryTableColumn> columns = new ArrayList<>();
final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel().getEntityBinding(entityDescriptor.getEntityName());
final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister().getIdentifierGenerator();
final boolean identityColumn = identifierGenerator instanceof PostInsertIdentifierGenerator;
final boolean hasOptimizer;
if (identityColumn) {
hasOptimizer = false;
final Iterator<JdbcMapping> jdbcMappings = entityDescriptor.getIdentifierMapping().getJdbcMappings().iterator();
for (Column column : entityBinding.getKey().getColumns()) {
final JdbcMapping jdbcMapping = jdbcMappings.next();
columns.add(new TemporaryTableColumn(temporaryTable, ENTITY_TABLE_IDENTITY_COLUMN, jdbcMapping, column.getSqlType(dialect, runtimeModelCreationContext.getMetadata()) + " " + dialect.getIdentityColumnSupport().getIdentityColumnString(column.getSqlTypeCode(runtimeModelCreationContext.getMetadata())), // column.isNullable()
true, true));
}
} else {
if (identifierGenerator instanceof OptimizableGenerator) {
final Optimizer optimizer = ((OptimizableGenerator) identifierGenerator).getOptimizer();
hasOptimizer = optimizer != null && optimizer.getIncrementSize() > 1;
} else {
hasOptimizer = false;
}
}
final Iterator<JdbcMapping> jdbcMappings = entityDescriptor.getIdentifierMapping().getJdbcMappings().iterator();
for (Column column : entityBinding.getKey().getColumns()) {
final JdbcMapping jdbcMapping = jdbcMappings.next();
columns.add(new TemporaryTableColumn(temporaryTable, column.getText(dialect), jdbcMapping, column.getSqlType(dialect, runtimeModelCreationContext.getMetadata()), // We have to set the identity column after the root table insert
column.isNullable() || identityColumn || hasOptimizer, !identityColumn && !hasOptimizer));
}
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
if (entityBinding.getDiscriminator() != null && !discriminatorMapping.isFormula()) {
final Column discriminator = entityBinding.getDiscriminator().getColumns().get(0);
columns.add(new TemporaryTableColumn(temporaryTable, discriminator.getText(dialect), discriminatorMapping.getJdbcMapping(), discriminator.getSqlType(dialect, runtimeModelCreationContext.getMetadata()), // We have to set the identity column after the root table insert
discriminator.isNullable()));
}
// Collect all columns for all entity subtype attributes
entityDescriptor.visitSubTypeAttributeMappings(attribute -> {
if (!(attribute instanceof PluralAttributeMapping)) {
final SimpleValue value = (SimpleValue) entityBinding.getSubclassProperty(attribute.getAttributeName()).getValue();
final Iterator<Selectable> columnIterator = value.getConstraintColumnIterator();
attribute.forEachSelectable((columnIndex, selection) -> {
final Selectable selectable = columnIterator.next();
if (selectable instanceof Column) {
final Column column = (Column) selectable;
columns.add(new TemporaryTableColumn(temporaryTable, selectable.getText(dialect), selection.getJdbcMapping(), column.getSqlType(dialect, runtimeModelCreationContext.getMetadata()), // Treat regular temporary table columns as nullable for simplicity
true));
}
});
}
});
if (hasOptimizer) {
// We add a special row number column that we can use to identify and join rows
final BasicType<Integer> integerBasicType = entityDescriptor.getEntityPersister().getFactory().getTypeConfiguration().getBasicTypeForJavaType(Integer.class);
final String rowNumberType;
if (dialect.supportsWindowFunctions()) {
rowNumberType = dialect.getTypeName(integerBasicType.getJdbcType().getJdbcTypeCode(), dialect.getSizeStrategy().resolveSize(integerBasicType.getJdbcType(), integerBasicType.getJavaTypeDescriptor(), null, null, null));
} else if (dialect.getIdentityColumnSupport().supportsIdentityColumns()) {
rowNumberType = dialect.getTypeName(integerBasicType.getJdbcType().getJdbcTypeCode(), dialect.getSizeStrategy().resolveSize(integerBasicType.getJdbcType(), integerBasicType.getJavaTypeDescriptor(), null, null, null)) + " " + dialect.getIdentityColumnSupport().getIdentityColumnString(integerBasicType.getJdbcType().getJdbcTypeCode());
} else {
LOG.multiTableInsertNotAvailable(entityBinding.getEntityName());
rowNumberType = dialect.getTypeName(integerBasicType.getJdbcType().getJdbcTypeCode(), dialect.getSizeStrategy().resolveSize(integerBasicType.getJdbcType(), integerBasicType.getJavaTypeDescriptor(), null, null, null));
}
columns.add(new TemporaryTableColumn(temporaryTable, "rn_", integerBasicType, rowNumberType, false, true));
}
return columns;
});
}
use of org.hibernate.metamodel.mapping.EntityDiscriminatorMapping in project hibernate-orm by hibernate.
the class ResultMementoEntityJpa method resolve.
@Override
public ResultBuilderEntityValued resolve(Consumer<String> querySpaceConsumer, ResultSetMappingResolutionContext context) {
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
final BasicValuedFetchBuilder discriminatorFetchBuilder;
if (discriminatorMapping == null) {
assert discriminatorMemento == null;
discriminatorFetchBuilder = null;
} else {
if (discriminatorMemento != null) {
discriminatorFetchBuilder = (BasicValuedFetchBuilder) discriminatorMemento.resolve(this, querySpaceConsumer, context);
} else {
discriminatorFetchBuilder = new ImplicitFetchBuilderBasic(navigablePath, discriminatorMapping);
}
}
final HashMap<String, FetchBuilder> explicitFetchBuilderMap = new HashMap<>();
// If there are no explicit fetches, we don't register DELAYED builders to get implicit fetching of all basic fetchables
if (!explicitFetchMementoMap.isEmpty()) {
explicitFetchMementoMap.forEach((relativePath, fetchMemento) -> explicitFetchBuilderMap.put(relativePath, fetchMemento.resolve(this, querySpaceConsumer, context)));
final boolean isEnhancedForLazyLoading = entityDescriptor.getRepresentationStrategy().isBytecodeEnhanced();
// Implicit basic fetches are DELAYED by default, so register fetch builders for the remaining basic fetchables
entityDescriptor.visitAttributeMappings(attributeMapping -> {
final Function<String, FetchBuilder> fetchBuilderCreator;
if (attributeMapping instanceof BasicValuedModelPart) {
fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(navigablePath.append(k), (BasicValuedModelPart) attributeMapping, isEnhancedForLazyLoading);
explicitFetchBuilderMap.computeIfAbsent(attributeMapping.getFetchableName(), fetchBuilderCreator);
}
});
}
return new CompleteResultBuilderEntityJpa(navigablePath, entityDescriptor, lockMode, discriminatorFetchBuilder, explicitFetchBuilderMap);
}
use of org.hibernate.metamodel.mapping.EntityDiscriminatorMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitLiteral.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// General expressions
@Override
public Expression visitLiteral(SqmLiteral<?> literal) {
if (literal instanceof SqmLiteralNull) {
MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible == null) {
mappingModelExpressible = determineCurrentExpressible(literal);
}
if (mappingModelExpressible instanceof BasicValuedMapping) {
return new QueryLiteral<>(null, (BasicValuedMapping) mappingModelExpressible);
}
final MappingModelExpressible<?> keyExpressible = getKeyExpressible(mappingModelExpressible);
if (keyExpressible == null) {
// Default to the Object type
return new QueryLiteral<>(null, basicType(Object.class));
}
final List<Expression> expressions = new ArrayList<>(keyExpressible.getJdbcTypeCount());
keyExpressible.forEachJdbcType((index, jdbcMapping) -> expressions.add(new QueryLiteral<>(null, (BasicValuedMapping) jdbcMapping)));
return new SqlTuple(expressions, mappingModelExpressible);
}
final MappingModelExpressible<?> inferableExpressible = resolveInferredType();
if (inferableExpressible instanceof ConvertibleModelPart) {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) inferableExpressible;
if (convertibleModelPart.getValueConverter() != null) {
return new QueryLiteral<>(literal.getLiteralValue(), convertibleModelPart);
}
} else // Special case for when we create an entity literal through the JPA CriteriaBuilder.literal API
if (inferableExpressible instanceof EntityDiscriminatorMapping) {
final EntityDiscriminatorMapping discriminatorMapping = (EntityDiscriminatorMapping) inferableExpressible;
final Object literalValue = literal.getLiteralValue();
final EntityPersister mappingDescriptor;
if (literalValue instanceof Class<?>) {
mappingDescriptor = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor((Class<?>) literalValue);
} else {
final JavaType<?> javaType = discriminatorMapping.getJdbcMapping().getJavaTypeDescriptor();
final Object discriminatorValue;
if (javaType.getJavaTypeClass().isInstance(literalValue)) {
discriminatorValue = literalValue;
} else if (literalValue instanceof CharSequence) {
discriminatorValue = javaType.fromString((CharSequence) literalValue);
} else if (creationContext.getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled()) {
discriminatorValue = literalValue;
} else {
discriminatorValue = javaType.coerce(literalValue, null);
}
final String entityName = discriminatorMapping.getConcreteEntityNameForDiscriminatorValue(discriminatorValue);
mappingDescriptor = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(entityName);
}
return new EntityTypeLiteral(mappingDescriptor);
}
final MappingModelExpressible<?> expressible;
final MappingModelExpressible<?> localExpressible = SqmMappingModelHelper.resolveMappingModelExpressible(literal, creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel(), getFromClauseAccess()::findTableGroup);
if (localExpressible == null) {
expressible = getElementExpressible(inferableExpressible);
} else {
final MappingModelExpressible<?> elementExpressible = getElementExpressible(localExpressible);
if (elementExpressible instanceof BasicType) {
expressible = InferredBasicValueResolver.resolveSqlTypeIndicators(this, (BasicType) elementExpressible, literal.getJavaTypeDescriptor());
} else {
expressible = elementExpressible;
}
}
if (expressible instanceof EntityIdentifierMapping && literal.getNodeType() instanceof EntityTypeImpl) {
return new QueryLiteral<>(((EntityIdentifierMapping) expressible).getIdentifier(literal.getLiteralValue()), (BasicValuedMapping) expressible);
}
if (expressible instanceof BasicValuedMapping) {
return new QueryLiteral<>(literal.getLiteralValue(), (BasicValuedMapping) expressible);
}
// Handling other values might seem unnecessary, but with JPA Criteria it is totally possible to have such literals
if (expressible instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart embeddableValuedModelPart = (EmbeddableValuedModelPart) expressible;
final List<Expression> list = new ArrayList<>(embeddableValuedModelPart.getJdbcTypeCount());
embeddableValuedModelPart.forEachJdbcValue(literal.getLiteralValue(), null, (selectionIndex, value, jdbcMapping) -> list.add(new QueryLiteral<>(value, (BasicValuedMapping) jdbcMapping)), null);
return new SqlTuple(list, expressible);
} else if (expressible instanceof EntityValuedModelPart) {
final EntityValuedModelPart entityValuedModelPart = (EntityValuedModelPart) expressible;
final Object associationKey;
final ModelPart associationKeyPart;
if (entityValuedModelPart instanceof Association) {
final Association association = (Association) entityValuedModelPart;
final ForeignKeyDescriptor foreignKeyDescriptor = association.getForeignKeyDescriptor();
associationKey = foreignKeyDescriptor.getAssociationKeyFromSide(literal.getLiteralValue(), association.getSideNature().inverse(), null);
associationKeyPart = foreignKeyDescriptor.getPart(association.getSideNature());
} else {
final EntityIdentifierMapping identifierMapping = entityValuedModelPart.getEntityMappingType().getIdentifierMapping();
associationKeyPart = identifierMapping;
associationKey = identifierMapping.getIdentifier(literal.getLiteralValue(), null);
}
if (associationKeyPart instanceof BasicValuedMapping) {
return new QueryLiteral<>(associationKey, (BasicValuedMapping) associationKeyPart);
} else {
final List<Expression> list = new ArrayList<>(associationKeyPart.getJdbcTypeCount());
associationKeyPart.forEachJdbcValue(associationKey, null, (selectionIndex, value, jdbcMapping) -> list.add(new QueryLiteral<>(value, (BasicValuedMapping) jdbcMapping)), null);
return new SqlTuple(list, associationKeyPart);
}
} else {
return new QueryLiteral<>(literal.getLiteralValue(), creationContext.getSessionFactory().getTypeConfiguration().getBasicTypeRegistry().getRegisteredType(((BasicSqmPathSource<?>) literal.getNodeType()).getSqmPathType().getJavaType().getName()));
}
}
Aggregations