Search in sources :

Example 1 with EnumJavaType

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);
}
Also used : Serializable(java.io.Serializable) SerializableJavaType(org.hibernate.type.descriptor.java.SerializableJavaType) SerializableType(org.hibernate.type.SerializableType) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) ObjectJdbcType(org.hibernate.type.descriptor.jdbc.ObjectJdbcType) MappingException(org.hibernate.MappingException) BasicValue(org.hibernate.mapping.BasicValue) TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) ObjectJdbcType(org.hibernate.type.descriptor.jdbc.ObjectJdbcType) EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) Column(org.hibernate.mapping.Column)

Example 2 with EnumJavaType

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);
}
Also used : NamedEnumValueConverter(org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter) EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) EnumType(org.hibernate.type.EnumType) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) Test(org.junit.jupiter.api.Test) BaseUnitTest(org.hibernate.testing.orm.junit.BaseUnitTest)

Example 3 with EnumJavaType

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));
}
Also used : NamedEnumValueConverter(org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) HibernateException(org.hibernate.HibernateException) OrdinalEnumValueConverter(org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter)

Example 4 with EnumJavaType

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());
    }
}
Also used : NamedEnumValueConverter(org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter) AssertionFailure(org.hibernate.AssertionFailure) HibernateException(org.hibernate.HibernateException) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) OrdinalEnumValueConverter(org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter)

Example 5 with EnumJavaType

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);
}
Also used : EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) OrdinalEnumValueConverter(org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter) EnumType(org.hibernate.type.EnumType) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) Test(org.junit.jupiter.api.Test) BaseUnitTest(org.hibernate.testing.orm.junit.BaseUnitTest)

Aggregations

EnumJavaType (org.hibernate.type.descriptor.java.EnumJavaType)5 NamedEnumValueConverter (org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter)3 OrdinalEnumValueConverter (org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter)3 HibernateException (org.hibernate.HibernateException)2 BaseUnitTest (org.hibernate.testing.orm.junit.BaseUnitTest)2 EnumType (org.hibernate.type.EnumType)2 BasicJavaType (org.hibernate.type.descriptor.java.BasicJavaType)2 JdbcType (org.hibernate.type.descriptor.jdbc.JdbcType)2 TypeConfiguration (org.hibernate.type.spi.TypeConfiguration)2 Test (org.junit.jupiter.api.Test)2 Serializable (java.io.Serializable)1 AssertionFailure (org.hibernate.AssertionFailure)1 MappingException (org.hibernate.MappingException)1 BasicValue (org.hibernate.mapping.BasicValue)1 Column (org.hibernate.mapping.Column)1 SerializableType (org.hibernate.type.SerializableType)1 SerializableJavaType (org.hibernate.type.descriptor.java.SerializableJavaType)1 TemporalJavaType (org.hibernate.type.descriptor.java.TemporalJavaType)1 ObjectJdbcType (org.hibernate.type.descriptor.jdbc.ObjectJdbcType)1