use of org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators in project hibernate-orm by hibernate.
the class SimpleValue method buildAttributeConverterTypeAdapter.
private <T> AttributeConverterTypeAdapter<T> buildAttributeConverterTypeAdapter(JpaAttributeConverter<T, ?> jpaAttributeConverter) {
JavaType<T> domainJavaType = jpaAttributeConverter.getDomainJavaType();
JavaType<?> relationalJavaType = jpaAttributeConverter.getRelationalJavaType();
// build the SqlTypeDescriptor adapter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Going back to the illustration, this should be a SqlTypeDescriptor that handles the Integer <-> String
// conversions. This is the more complicated piece. First we need to determine the JDBC type code
// corresponding to the AttributeConverter's declared "databaseColumnJavaType" (how we read that value out
// of ResultSets). See JdbcTypeJavaClassMappings for details. Again, given example, this should return
// VARCHAR/CHAR
final JdbcType recommendedJdbcType = relationalJavaType.getRecommendedJdbcType(// todo (6.0) : handle the other JdbcRecommendedSqlTypeMappingContext methods
new JdbcTypeIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return metadata.getTypeConfiguration();
}
@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return buildingContext.getBuildingOptions().getDefaultTimeZoneStorage();
}
});
int jdbcTypeCode = recommendedJdbcType.getDefaultSqlTypeCode();
if (isLob()) {
if (LobTypeMappings.isMappedToKnownLobCode(jdbcTypeCode)) {
jdbcTypeCode = LobTypeMappings.getLobCodeTypeMapping(jdbcTypeCode);
} else {
if (Serializable.class.isAssignableFrom(domainJavaType.getJavaTypeClass())) {
jdbcTypeCode = Types.BLOB;
} else {
throw new IllegalArgumentException(String.format(Locale.ROOT, "JDBC type-code [%s (%s)] not known to have a corresponding LOB equivalent, and Java type is not Serializable (to use BLOB)", jdbcTypeCode, JdbcTypeNameMapper.getTypeName(jdbcTypeCode)));
}
}
}
if (isNationalized()) {
jdbcTypeCode = NationalizedTypeMappings.toNationalizedTypeCode(jdbcTypeCode);
}
// todo : cache the AttributeConverterTypeAdapter in case that AttributeConverter is applied multiple times.
return new AttributeConverterTypeAdapter<>(ConverterDescriptor.TYPE_NAME_PREFIX + jpaAttributeConverter.getConverterJavaType().getJavaType().getTypeName(), String.format("BasicType adapter for AttributeConverter<%s,%s>", domainJavaType.getJavaType().getTypeName(), relationalJavaType.getJavaType().getTypeName()), jpaAttributeConverter, // calls into the binding/extraction process...
new AttributeConverterJdbcTypeAdapter(jpaAttributeConverter, metadata.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor(jdbcTypeCode), relationalJavaType), relationalJavaType, domainJavaType, null);
}
use of org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators in project hibernate-orm by hibernate.
the class VersionResolution method from.
// todo (6.0) : support explicit JTD?
// todo (6.0) : support explicit STD?
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <E> VersionResolution<E> from(Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess, Function<TypeConfiguration, BasicJavaType> explicitJtdAccess, Function<TypeConfiguration, JdbcType> explicitStdAccess, TimeZoneStorageType timeZoneStorageType, TypeConfiguration typeConfiguration, @SuppressWarnings("unused") MetadataBuildingContext context) {
// todo (6.0) : add support for Dialect-specific interpretation?
final java.lang.reflect.Type implicitJavaType = implicitJavaTypeAccess.apply(typeConfiguration);
final JavaType registered = typeConfiguration.getJavaTypeRegistry().resolveDescriptor(implicitJavaType);
final BasicJavaType jtd = (BasicJavaType) registered;
final JdbcType recommendedJdbcType = jtd.getRecommendedJdbcType(new JdbcTypeIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public TemporalType getTemporalPrecision() {
// if it is a temporal version, it needs to be a TIMESTAMP
return TemporalType.TIMESTAMP;
}
@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
if (timeZoneStorageType != null) {
switch(timeZoneStorageType) {
case NATIVE:
return TimeZoneStorageStrategy.NATIVE;
case NORMALIZE:
return TimeZoneStorageStrategy.NORMALIZE;
}
}
return context.getBuildingOptions().getDefaultTimeZoneStorage();
}
});
final BasicType<?> basicType = typeConfiguration.getBasicTypeRegistry().resolve(jtd, recommendedJdbcType);
final BasicType legacyType = typeConfiguration.getBasicTypeRegistry().getRegisteredType(jtd.getJavaType());
assert legacyType.getJdbcType().equals(recommendedJdbcType);
return new VersionResolution<>(jtd, recommendedJdbcType, basicType, legacyType);
}
use of org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators in project hibernate-orm by hibernate.
the class ArgumentTypesValidator method validate.
/**
* We do an initial validation phase with just the SQM tree, even though we don't
* have all typing information available here (in particular, we don't have the
* final JDBC type codes for things with converters) because this is the phase
* that is run at startup for named queries, and can be done in an IDE.
*/
@Override
public void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, QueryEngine queryEngine) {
delegate.validate(arguments, functionName, queryEngine);
int count = 0;
for (SqmTypedNode<?> argument : arguments) {
JdbcTypeIndicators indicators = queryEngine.getTypeConfiguration().getCurrentBaseSqlTypeIndicators();
SqmExpressible<?> nodeType = argument.getNodeType();
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
if (nodeType != null) {
JavaType<?> javaType = nodeType.getExpressibleJavaType();
if (javaType != null) {
try {
JdbcType jdbcType = javaType.getRecommendedJdbcType(indicators);
checkType(count, functionName, type, jdbcType.getJdbcTypeCode(), javaType.getJavaTypeClass());
} catch (JdbcTypeRecommendationException e) {
// it's a converter or something like that, and we will check it later
}
}
switch(type) {
case TEMPORAL_UNIT:
if (!(argument instanceof SqmExtractUnit) && !(argument instanceof SqmDurationUnit)) {
throwError(type, Object.class, functionName, count);
}
break;
// something crazy by the parser
case TRIM_SPEC:
if (!(argument instanceof SqmTrimSpecification)) {
throwError(type, Object.class, functionName, count);
}
break;
case COLLATION:
if (!(argument instanceof SqmCollation)) {
throwError(type, Object.class, functionName, count);
}
break;
}
} else {
// TODO: appropriate error?
}
}
}
use of org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators in project hibernate-orm by hibernate.
the class ResultSetAccess method resolveType.
@Override
default <J> BasicType<J> resolveType(int position, JavaType<J> explicitJavaType, SessionFactoryImplementor sessionFactory) {
final TypeConfiguration typeConfiguration = getFactory().getTypeConfiguration();
final JdbcServices jdbcServices = getFactory().getJdbcServices();
try {
final ResultSetMetaData metaData = getResultSet().getMetaData();
final String columnTypeName = metaData.getColumnTypeName(position);
final int columnType = metaData.getColumnType(position);
final int scale = metaData.getScale(position);
final int precision = metaData.getPrecision(position);
final int displaySize = metaData.getColumnDisplaySize(position);
final Dialect dialect = jdbcServices.getDialect();
final int length = dialect.resolveSqlTypeLength(columnTypeName, columnType, precision, scale, displaySize);
final JdbcType resolvedJdbcType = dialect.resolveSqlTypeDescriptor(columnTypeName, columnType, length, scale, typeConfiguration.getJdbcTypeRegistry());
final JavaType<J> javaType;
final JdbcType jdbcType;
// If there is an explicit JavaType, then prefer its recommended JDBC type
if (explicitJavaType != null) {
javaType = explicitJavaType;
jdbcType = explicitJavaType.getRecommendedJdbcType(new JdbcTypeIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public long getColumnLength() {
return length;
}
@Override
public int getColumnPrecision() {
return precision;
}
@Override
public int getColumnScale() {
return scale;
}
@Override
public EnumType getEnumeratedType() {
return resolvedJdbcType.isNumber() ? EnumType.ORDINAL : EnumType.STRING;
}
});
} else {
jdbcType = resolvedJdbcType;
javaType = jdbcType.getJdbcRecommendedJavaTypeMapping(length, scale, typeConfiguration);
}
return typeConfiguration.getBasicTypeRegistry().resolve(javaType, jdbcType);
} catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert(e, "Unable to determine JDBC type code for ResultSet position " + position);
}
}
Aggregations