use of org.hibernate.type.descriptor.java.EnumJavaType in project hibernate-orm by hibernate.
the class InferredBasicValueResolver method from.
public static <T> BasicValue.Resolution<T> from(BasicJavaType<T> explicitJavaType, JdbcType explicitJdbcType, Type resolvedJavaType, Supplier<JavaType<T>> reflectedJtdResolver, JdbcTypeIndicators stdIndicators, Table table, Selectable selectable, String ownerName, String propertyName, TypeConfiguration typeConfiguration) {
final JavaType<T> reflectedJtd = reflectedJtdResolver.get();
// NOTE : the distinction that is made below wrt `explicitJavaType` and `reflectedJtd` is
// needed temporarily to trigger "legacy resolution" versus "ORM6 resolution. Yes, it
// makes the code a little more complicated but the benefit is well worth it - saving memory
final BasicType<T> jdbcMapping;
final BasicType<T> legacyType;
if (explicitJavaType != null) {
if (explicitJdbcType != null) {
// we also have an explicit JdbcType
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, explicitJdbcType);
legacyType = jdbcMapping;
} else {
if (explicitJavaType instanceof TemporalJavaType) {
return fromTemporal((TemporalJavaType<T>) explicitJavaType, null, null, resolvedJavaType, stdIndicators, typeConfiguration);
}
// we need to infer the JdbcType and use that to build the value-mapping
final JdbcType inferredJdbcType = explicitJavaType.getRecommendedJdbcType(stdIndicators);
if (inferredJdbcType instanceof ObjectJdbcType) {
if (explicitJavaType instanceof EnumJavaType) {
return fromEnum((EnumJavaType) reflectedJtd, explicitJavaType, null, stdIndicators, typeConfiguration);
} else if (explicitJavaType instanceof TemporalJavaType) {
return fromTemporal((TemporalJavaType<T>) reflectedJtd, explicitJavaType, null, resolvedJavaType, stdIndicators, typeConfiguration);
} else if (explicitJavaType instanceof SerializableJavaType || explicitJavaType.getJavaType() instanceof Serializable) {
legacyType = new SerializableType(explicitJavaType);
jdbcMapping = legacyType;
} else {
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, inferredJdbcType);
legacyType = jdbcMapping;
}
} else {
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, inferredJdbcType);
legacyType = jdbcMapping;
}
}
} else if (reflectedJtd != null) {
// we were able to determine the "reflected java-type"
if (explicitJdbcType != null) {
// we also have an explicit JdbcType
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd, explicitJdbcType);
legacyType = jdbcMapping;
} else {
if (reflectedJtd instanceof EnumJavaType) {
return fromEnum((EnumJavaType) reflectedJtd, null, null, stdIndicators, typeConfiguration);
} else if (reflectedJtd instanceof TemporalJavaType) {
return fromTemporal((TemporalJavaType<T>) reflectedJtd, null, null, resolvedJavaType, stdIndicators, typeConfiguration);
} else {
// see if there is a registered BasicType for this JavaType and, if so, use it.
// this mimics the legacy handling
final BasicType<T> registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType(reflectedJtd.getJavaType());
if (registeredType != null) {
// so here is the legacy resolution
legacyType = resolveSqlTypeIndicators(stdIndicators, registeredType, reflectedJtd);
jdbcMapping = legacyType;
} else {
// there was not a "legacy" BasicType registration, so use `JavaType#getRecommendedJdbcType`, if
// one, to create a mapping
final JdbcType recommendedJdbcType = reflectedJtd.getRecommendedJdbcType(stdIndicators);
if (recommendedJdbcType != null) {
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd, recommendedJdbcType);
legacyType = jdbcMapping;
} else if (reflectedJtd instanceof SerializableJavaType || Serializable.class.isAssignableFrom(reflectedJtd.getJavaTypeClass())) {
legacyType = new SerializableType(reflectedJtd);
jdbcMapping = legacyType;
} else {
// let this fall through to the exception creation below
legacyType = null;
jdbcMapping = null;
}
}
}
}
} else {
if (explicitJdbcType != null) {
// we have an explicit STD, but no JTD - infer JTD
// - NOTE : yes its an odd case, but its easy to implement here, so...
Integer length = null;
Integer scale = null;
if (selectable instanceof Column) {
final Column column = (Column) selectable;
if (column.getPrecision() != null && column.getPrecision() > 0) {
length = column.getPrecision();
scale = column.getScale();
} else if (column.getLength() != null) {
if (column.getLength() > (long) Integer.MAX_VALUE) {
length = Integer.MAX_VALUE;
} else {
length = column.getLength().intValue();
}
}
}
final BasicJavaType<T> recommendedJtd = explicitJdbcType.getJdbcRecommendedJavaTypeMapping(length, scale, typeConfiguration);
jdbcMapping = resolveSqlTypeIndicators(stdIndicators, typeConfiguration.getBasicTypeRegistry().resolve(recommendedJtd, explicitJdbcType), recommendedJtd);
legacyType = jdbcMapping;
} else {
throw new MappingException("Could not determine JavaType nor JdbcType to use" + " for BasicValue: owner = " + ownerName + "; property = " + propertyName + "; table = " + table.getName() + "; column = " + selectable.getText());
}
}
if (jdbcMapping == null) {
throw new MappingException("Could not determine JavaType nor JdbcType to use" + "" + " for " + ((BasicValue) stdIndicators).getResolvedJavaType() + "; table = " + table.getName() + "; column = " + selectable.getText());
}
return new InferredBasicValueResolution<>(jdbcMapping, jdbcMapping.getJavaTypeDescriptor(), jdbcMapping.getJavaTypeDescriptor(), jdbcMapping.getJdbcType(), null, legacyType, null);
}
use of org.hibernate.type.descriptor.java.EnumJavaType in project hibernate-orm by hibernate.
the class TestEnumTypeSerialization method testNamedSerializability.
@Test
public void testNamedSerializability() {
TypeConfiguration typeConfiguration = new TypeConfiguration();
final EnumJavaType<UnspecifiedEnumTypeEntity.E1> enumJtd = (EnumJavaType) typeConfiguration.getJavaTypeRegistry().resolveDescriptor(UnspecifiedEnumTypeEntity.E1.class);
final NamedEnumValueConverter valueConverter = new NamedEnumValueConverter(enumJtd, VarcharJdbcType.INSTANCE, StringJavaType.INSTANCE);
final EnumType<UnspecifiedEnumTypeEntity.E1> enumType = new EnumType<>(UnspecifiedEnumTypeEntity.E1.class, valueConverter, typeConfiguration);
SerializationHelper.clone(enumType);
}
use of org.hibernate.type.descriptor.java.EnumJavaType in project hibernate-orm by hibernate.
the class EnumType method interpretParameters.
private EnumValueConverter<T, Object> interpretParameters(Properties parameters) {
// noinspection rawtypes
final EnumJavaType enumJavaType = (EnumJavaType) typeConfiguration.getJavaTypeRegistry().getDescriptor(enumClass);
// this method should only be called for hbm.xml handling
assert parameters.get(PARAMETER_TYPE) == null;
final LocalJdbcTypeIndicators localIndicators = new LocalJdbcTypeIndicators(// use ORDINAL as default for hbm.xml mappings
jakarta.persistence.EnumType.ORDINAL, // etc
-1L, null);
final BasicJavaType<?> stringJavaType = (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(String.class);
final BasicJavaType<?> integerJavaType = (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(Integer.class);
if (parameters.containsKey(NAMED)) {
final boolean useNamed = ConfigurationHelper.getBoolean(NAMED, parameters);
if (useNamed) {
// noinspection rawtypes
return new NamedEnumValueConverter(enumJavaType, stringJavaType.getRecommendedJdbcType(localIndicators), stringJavaType);
} else {
// noinspection rawtypes
return new OrdinalEnumValueConverter(enumJavaType, integerJavaType.getRecommendedJdbcType(localIndicators), typeConfiguration.getJavaTypeRegistry().getDescriptor(Integer.class));
}
}
if (parameters.containsKey(TYPE)) {
final int type = Integer.decode((String) parameters.get(TYPE));
if (isNumericType(type)) {
// noinspection rawtypes
return new OrdinalEnumValueConverter(enumJavaType, integerJavaType.getRecommendedJdbcType(localIndicators), typeConfiguration.getJavaTypeRegistry().getDescriptor(Integer.class));
} else if (isCharacterType(type)) {
// noinspection rawtypes
return new NamedEnumValueConverter(enumJavaType, stringJavaType.getRecommendedJdbcType(localIndicators), stringJavaType);
} else {
throw new HibernateException(String.format(Locale.ENGLISH, "Passed JDBC type code [%s] not recognized as numeric nor character", type));
}
}
// the fallback
return new OrdinalEnumValueConverter(enumJavaType, integerJavaType.getRecommendedJdbcType(localIndicators), typeConfiguration.getJavaTypeRegistry().getDescriptor(Integer.class));
}
use of org.hibernate.type.descriptor.java.EnumJavaType in project hibernate-orm by hibernate.
the class EnumType method setParameterValues.
@Override
public void setParameterValues(Properties parameters) {
// IMPL NOTE: we handle 2 distinct cases here:
// 1) we are passed a ParameterType instance in the incoming Properties - generally
// speaking this indicates the annotation-binding case, and the passed ParameterType
// represents information about the attribute and annotation
// 2) we are not passed a ParameterType - generally this indicates a hbm.xml binding case.
final ParameterType reader = (ParameterType) parameters.get(PARAMETER_TYPE);
// handles hbm.xml
if (reader != null) {
enumClass = (Class<T>) reader.getReturnedClass().asSubclass(Enum.class);
final Long columnLength = reader.getColumnLengths()[0];
final boolean isOrdinal;
final jakarta.persistence.EnumType enumType = getEnumType(reader);
if (enumType == null) {
isOrdinal = true;
} else if (jakarta.persistence.EnumType.ORDINAL.equals(enumType)) {
isOrdinal = true;
} else if (jakarta.persistence.EnumType.STRING.equals(enumType)) {
isOrdinal = false;
} else {
throw new AssertionFailure("Unknown EnumType: " + enumType);
}
final EnumJavaType enumJavaType = (EnumJavaType) typeConfiguration.getJavaTypeRegistry().getDescriptor(enumClass);
final LocalJdbcTypeIndicators indicators = new LocalJdbcTypeIndicators(enumType, columnLength, reader);
final BasicJavaType<?> relationalJavaType = resolveRelationalJavaType(indicators, enumJavaType);
final JdbcType jdbcType = relationalJavaType.getRecommendedJdbcType(indicators);
if (isOrdinal) {
this.enumValueConverter = new OrdinalEnumValueConverter(enumJavaType, jdbcType, relationalJavaType);
} else {
this.enumValueConverter = new NamedEnumValueConverter(enumJavaType, jdbcType, relationalJavaType);
}
this.jdbcType = jdbcType;
} else {
final String enumClassName = (String) parameters.get(ENUM);
try {
enumClass = ReflectHelper.classForName(enumClassName, this.getClass()).asSubclass(Enum.class);
} catch (ClassNotFoundException exception) {
throw new HibernateException("Enum class not found: " + enumClassName, exception);
}
this.enumValueConverter = interpretParameters(parameters);
this.jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor(enumValueConverter.getJdbcTypeCode());
}
this.jdbcValueExtractor = (ValueExtractor) jdbcType.getExtractor(enumValueConverter.getRelationalJavaType());
this.jdbcValueBinder = (ValueBinder) jdbcType.getBinder(enumValueConverter.getRelationalJavaType());
if (LOG.isDebugEnabled()) {
LOG.debugf("Using %s-based conversion for Enum %s", isOrdinal() ? "ORDINAL" : "NAMED", enumClass.getName());
}
}
use of org.hibernate.type.descriptor.java.EnumJavaType in project hibernate-orm by hibernate.
the class TestEnumTypeSerialization method testOrdinalSerializability.
@Test
public void testOrdinalSerializability() {
TypeConfiguration typeConfiguration = new TypeConfiguration();
final EnumJavaType<UnspecifiedEnumTypeEntity.E1> enumJtd = (EnumJavaType) typeConfiguration.getJavaTypeRegistry().resolveDescriptor(UnspecifiedEnumTypeEntity.E1.class);
final OrdinalEnumValueConverter valueConverter = new OrdinalEnumValueConverter(enumJtd, IntegerJdbcType.INSTANCE, IntegerJavaType.INSTANCE);
final EnumType<UnspecifiedEnumTypeEntity.E1> enumType = new EnumType<>(UnspecifiedEnumTypeEntity.E1.class, valueConverter, typeConfiguration);
SerializationHelper.clone(enumType);
}
Aggregations