use of org.hibernate.metamodel.mapping.ConvertibleModelPart in project hibernate-orm by hibernate.
the class QueryLiteral method bindParameterValue.
@Override
public void bindParameterValue(PreparedStatement statement, int startPosition, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) throws SQLException {
Object literalValue = getLiteralValue();
// Convert the literal value if needed to the JDBC type on demand to still serve the domain model type through getLiteralValue()
if (type instanceof ConvertibleModelPart) {
ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) type;
if (convertibleModelPart.getValueConverter() != null) {
// noinspection unchecked
literalValue = convertibleModelPart.getValueConverter().toRelationalValue(literalValue);
}
}
// noinspection unchecked
type.getJdbcMapping().getJdbcValueBinder().bind(statement, literalValue, startPosition, executionContext.getSession());
}
use of org.hibernate.metamodel.mapping.ConvertibleModelPart in project hibernate-orm by hibernate.
the class SqmUtil method createJdbcParameterBindings.
// public static JdbcParameterBindings buildJdbcParameterBindings(
// SqmStatement sqmStatement,
// JdbcParameterBySqmParameterAccess sqmInterpretation,
// ExecutionContext executionContext) {
// final DomainParameterXref domainParameterXref = DomainParameterXref.from( sqmStatement );
// final Map<QueryParameterImplementor<?>, Map<SqmParameter, List<JdbcParameter>>> jdbcParamsXref =
// generateJdbcParamsXref( domainParameterXref, sqmInterpretation );
// return createJdbcParameterBindings(
// executionContext.getDomainParameterBindingContext().getQueryParameterBindings(),
// domainParameterXref,
// jdbcParamsXref,
// executionContext.getSession()
// );
// }
// public static JdbcParameterBindings buildJdbcParameterBindings(
// SqmStatement sqmStatement,
// Map<QueryParameterImplementor<?>, Map<SqmParameter, List<JdbcParameter>>> jdbcParamsXref,
// ExecutionContext executionContext) {
// final DomainParameterXref domainParameterXref = DomainParameterXref.from( sqmStatement );
// return createJdbcParameterBindings(
// executionContext.getDomainParameterBindingContext().getQueryParameterBindings(),
// domainParameterXref,
// jdbcParamsXref,
// executionContext.getSession()
// );
// }
// public static JdbcParameterBindings buildJdbcParameterBindings(
// DomainParameterXref domainParameterXref,
// Map<QueryParameterImplementor<?>, Map<SqmParameter, List<JdbcParameter>>> jdbcParamsXref,
// ExecutionContext executionContext) {
// return createJdbcParameterBindings(
// executionContext.getDomainParameterBindingContext().getQueryParameterBindings(),
// domainParameterXref,
// jdbcParamsXref,
// executionContext.getSession()
// );
// }
public static JdbcParameterBindings createJdbcParameterBindings(QueryParameterBindings domainParamBindings, DomainParameterXref domainParameterXref, Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamXref, MappingMetamodel domainModel, Function<NavigablePath, TableGroup> tableGroupLocator, SqmParameterMappingModelResolutionAccess mappingModelResolutionAccess, SharedSessionContractImplementor session) {
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(domainParameterXref.getSqmParameterCount());
for (Map.Entry<QueryParameterImplementor<?>, List<SqmParameter<?>>> entry : domainParameterXref.getSqmParamByQueryParam().entrySet()) {
final QueryParameterImplementor<?> queryParam = entry.getKey();
final List<SqmParameter<?>> sqmParameters = entry.getValue();
final QueryParameterBinding<?> domainParamBinding = domainParamBindings.getBinding(queryParam);
final Map<SqmParameter<?>, List<List<JdbcParameter>>> jdbcParamMap = jdbcParamXref.get(queryParam);
for (SqmParameter<?> sqmParameter : sqmParameters) {
final Bindable parameterType = determineParameterType(domainParamBinding, queryParam, sqmParameters, mappingModelResolutionAccess, session.getFactory());
final List<List<JdbcParameter>> jdbcParamsBinds = jdbcParamMap.get(sqmParameter);
if (jdbcParamsBinds == null) {
// is replaced with an alias reference expression, which can happen for JPA Criteria queries
continue;
}
if (!domainParamBinding.isBound()) {
for (int i = 0; i < jdbcParamsBinds.size(); i++) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get(i);
parameterType.forEachJdbcType((position, jdbcType) -> {
jdbcParameterBindings.addBinding(jdbcParams.get(position), new JdbcParameterBindingImpl(jdbcType, null));
});
}
} else if (domainParamBinding.isMultiValued()) {
final Collection<?> bindValues = domainParamBinding.getBindValues();
final Iterator<?> valueItr = bindValues.iterator();
// the original SqmParameter is the one we are processing.. create a binding for it..
for (int i = 0; i < jdbcParamsBinds.size(); i++) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get(i);
createValueBindings(jdbcParameterBindings, queryParam, domainParamBinding, parameterType, jdbcParams, valueItr.next(), tableGroupLocator, session);
}
// an then one for each of the expansions
final List<SqmParameter<?>> expansions = domainParameterXref.getExpansions(sqmParameter);
assert expansions.size() == bindValues.size() - 1;
int expansionPosition = 0;
while (valueItr.hasNext()) {
final SqmParameter<?> expansionSqmParam = expansions.get(expansionPosition++);
final List<List<JdbcParameter>> jdbcParamBinds = jdbcParamMap.get(expansionSqmParam);
for (int i = 0; i < jdbcParamBinds.size(); i++) {
List<JdbcParameter> expansionJdbcParams = jdbcParamBinds.get(i);
createValueBindings(jdbcParameterBindings, queryParam, domainParamBinding, parameterType, expansionJdbcParams, valueItr.next(), tableGroupLocator, session);
}
}
} else if (domainParamBinding.getBindValue() == null) {
for (int i = 0; i < jdbcParamsBinds.size(); i++) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get(i);
for (int j = 0; j < jdbcParams.size(); j++) {
final JdbcParameter jdbcParameter = jdbcParams.get(j);
jdbcParameterBindings.addBinding(jdbcParameter, new JdbcParameterBindingImpl(null, null));
}
}
} else {
if (domainParamBinding.getType() instanceof AttributeConverterTypeAdapter || domainParamBinding.getType() instanceof ConvertibleModelPart) {
final BasicValueConverter valueConverter;
final JdbcMapping jdbcMapping;
if (domainParamBinding.getType() instanceof AttributeConverterTypeAdapter) {
final AttributeConverterTypeAdapter<?> adapter = (AttributeConverterTypeAdapter<?>) domainParamBinding.getType();
valueConverter = adapter.getAttributeConverter();
jdbcMapping = adapter.getJdbcMapping();
} else {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) domainParamBinding.getType();
valueConverter = convertibleModelPart.getValueConverter();
jdbcMapping = convertibleModelPart.getJdbcMapping();
}
if (valueConverter != null) {
final Object convertedValue = valueConverter.toRelationalValue(domainParamBinding.getBindValue());
for (int i = 0; i < jdbcParamsBinds.size(); i++) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get(i);
assert jdbcParams.size() == 1;
final JdbcParameter jdbcParameter = jdbcParams.get(0);
jdbcParameterBindings.addBinding(jdbcParameter, new JdbcParameterBindingImpl(jdbcMapping, convertedValue));
}
continue;
}
}
final Object bindValue = domainParamBinding.getBindValue();
for (int i = 0; i < jdbcParamsBinds.size(); i++) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get(i);
createValueBindings(jdbcParameterBindings, queryParam, domainParamBinding, parameterType, jdbcParams, bindValue, tableGroupLocator, session);
}
}
}
}
return jdbcParameterBindings;
}
use of org.hibernate.metamodel.mapping.ConvertibleModelPart in project hibernate-orm by hibernate.
the class ImplicitFetchBuilderBasic method buildFetch.
@Override
public BasicFetch<?> buildFetch(FetchParent parent, NavigablePath fetchPath, JdbcValuesMetadata jdbcResultsMetadata, BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver, DomainResultCreationState domainResultCreationState) {
final DomainResultCreationStateImpl creationStateImpl = ResultsHelper.impl(domainResultCreationState);
final TableGroup parentTableGroup = creationStateImpl.getFromClauseAccess().getTableGroup(parent.getNavigablePath());
final String table = fetchable.getContainingTableExpression();
final String column;
// In case of a formula we look for a result set position with the fetchable name
if (fetchable.isFormula()) {
column = fetchable.getFetchableName();
} else {
column = fetchable.getSelectionExpression();
}
final Expression expression = creationStateImpl.resolveSqlExpression(createColumnReferenceKey(parentTableGroup.resolveTableReference(fetchPath, table), fetchable.getSelectionExpression()), processingState -> {
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition(column);
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition(jdbcPosition);
return new ResultSetMappingSqlSelection(valuesArrayPosition, fetchable);
});
final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection(expression, fetchable.getJavaType(), domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration());
final BasicValueConverter<?, ?> valueConverter;
if (fetchable instanceof ConvertibleModelPart) {
valueConverter = ((ConvertibleModelPart) fetchable).getValueConverter();
} else {
valueConverter = null;
}
return new BasicFetch<>(sqlSelection.getValuesArrayPosition(), parent, fetchPath, fetchable, valueConverter, FetchTiming.IMMEDIATE, domainResultCreationState);
}
use of org.hibernate.metamodel.mapping.ConvertibleModelPart 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()));
}
}
use of org.hibernate.metamodel.mapping.ConvertibleModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitEnumLiteral.
@SuppressWarnings({ "raw", "unchecked" })
@Override
public Object visitEnumLiteral(SqmEnumLiteral<?> sqmEnumLiteral) {
final BasicValuedMapping inferrableType = (BasicValuedMapping) resolveInferredType();
if (inferrableType instanceof ConvertibleModelPart) {
final ConvertibleModelPart inferredPart = (ConvertibleModelPart) inferrableType;
final BasicValueConverter<Enum<?>, ?> valueConverter = inferredPart.getValueConverter();
final Object jdbcValue = valueConverter.toRelationalValue(sqmEnumLiteral.getEnumValue());
return new QueryLiteral<>(jdbcValue, inferredPart);
}
final EnumJavaType<?> enumJtd = sqmEnumLiteral.getExpressibleJavaType();
final JdbcType jdbcType = getTypeConfiguration().getJdbcTypeRegistry().getDescriptor(SqlTypes.TINYINT);
final BasicJavaType<Integer> relationalJtd = (BasicJavaType) getTypeConfiguration().getJavaTypeRegistry().getDescriptor(Integer.class);
final BasicType<?> jdbcMappingType = getTypeConfiguration().getBasicTypeRegistry().resolve(relationalJtd, jdbcType);
return new ConvertedQueryLiteral(sqmEnumLiteral.getEnumValue(), new OrdinalEnumValueConverter<>(enumJtd, jdbcType, relationalJtd), jdbcMappingType);
}
Aggregations