remove deprecated and very obsolete EnumType

This commit is contained in:
Gavin King 2024-12-31 16:31:00 +01:00
parent c44456ca5b
commit e15c9db29f
15 changed files with 369 additions and 73 deletions

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.type;
package org.hibernate.orm.test;
import java.io.Serializable;
import java.lang.annotation.Annotation;
@ -18,8 +18,8 @@ import org.hibernate.HibernateException;
import org.hibernate.annotations.Nationalized;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
@ -31,8 +31,6 @@ import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.LoggableUserType;
import org.jboss.logging.Logger;
import static jakarta.persistence.EnumType.ORDINAL;
import static jakarta.persistence.EnumType.STRING;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
@ -49,7 +47,6 @@ import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
@Deprecated(since="6.2", forRemoval=true)
public class EnumType<T extends Enum<T>>
implements EnhancedUserType<T>, DynamicParameterizedType, LoggableUserType, TypeConfigurationAware, Serializable {
private static final Logger LOG = CoreLogging.logger( EnumType.class );
public static final String ENUM = "enumClass";
public static final String NAMED = "useNamed";
@ -156,14 +153,6 @@ public class EnumType<T extends Enum<T>>
jdbcType = descriptor.getRecommendedJdbcType( indicators );
isOrdinal = indicators.getEnumeratedType() != STRING;
}
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Using %s-based conversion for Enum %s",
isOrdinal() ? "ORDINAL" : "NAMED",
enumClass.getName()
);
}
}
private jakarta.persistence.EnumType getEnumType(ParameterType reader) {

View File

@ -9,13 +9,14 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.orm.test.EnumType;
import org.hibernate.orm.test.annotations.enumerated.enums.FirstLetter;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* @author Janario Oliveira
*/
public class FirstLetterType extends org.hibernate.type.EnumType<FirstLetter> {
public class FirstLetterType extends EnumType<FirstLetter> {
@Override
public int getSqlType() {

View File

@ -9,13 +9,14 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.orm.test.EnumType;
import org.hibernate.orm.test.annotations.enumerated.enums.LastNumber;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* @author Janario Oliveira
*/
public class LastNumberType extends org.hibernate.type.EnumType<LastNumber> {
public class LastNumberType extends EnumType<LastNumber> {
@Override
public int getSqlType() {

View File

@ -64,7 +64,7 @@ public class ExtendedBeanManagerNotAvailableDuringTypeResolutionTest {
" </id>\n" +
" <property name=\"name\" />\n" +
" <property name=\"myEnum\" >\n" +
" <type name=\"org.hibernate.type.EnumType\">\n" +
" <type name=\"org.hibernate.orm.test.EnumType\">\n" +
" <param name=\"enumClass\">" + MyEnum.class.getName() + "</param>\n" +
" </type>\n" +
" </property>\n" +

View File

@ -6,7 +6,7 @@ package org.hibernate.orm.test.mapping.type.typedef;
import java.util.Properties;
import org.hibernate.type.EnumType;
import org.hibernate.orm.test.EnumType;
/**
* A simple user type where we force enums to be saved by name, not ordinal

View File

@ -16,20 +16,20 @@
</id>
<property name="gender" not-null="true">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<param name="enumClass">org.hibernate.orm.test.mapping.converted.enums.Gender</param>
<param name="type">12</param>
</type>
</property>
<property name="hairColor" not-null="true">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<param name="enumClass">org.hibernate.orm.test.mapping.converted.enums.HairColor</param>
</type>
</property>
<property name="originalHairColor">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<param name="enumClass">org.hibernate.orm.test.mapping.converted.enums.HairColor</param>
<param name="type">12</param>
</type>

View File

@ -12,13 +12,13 @@
<generator class="increment" />
</id>
<property name="enum1">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<!--<param name="useNamed">true</param>-->
<param name="enumClass">org.hibernate.orm.test.mapping.converted.enums.UnspecifiedEnumTypeEntity$E1</param>
</type>
</property>
<property name="enum2">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<!--<param name="useNamed">false</param>-->
<param name="enumClass">org.hibernate.orm.test.mapping.converted.enums.UnspecifiedEnumTypeEntity$E2</param>
</type>

View File

@ -11,7 +11,7 @@
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.orm.test.quote">
<typedef name="enumType" class="org.hibernate.type.EnumType">
<typedef name="enumType" class="org.hibernate.orm.test.EnumType">
<param name="enumClass">org.hibernate.orm.test.quote.DataPoint$DataPointEnum</param>
</typedef>

View File

@ -36,7 +36,7 @@
</property>
<property name="status">
<column name="status" not-null="true"/>
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.orm.test.EnumType">
<param name="type">12</param>
<param name="enumClass">org.hibernate.orm.test.query.hhh12076.SettlementStatus</param>
</type>

View File

@ -14,8 +14,6 @@ import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType;
import org.hibernate.type.Type;
/**
@ -58,21 +56,6 @@ public final class BasicMetadataGenerator {
return false;
}
private void mapEnumerationType(TypeSpecification typeDefinition, EnumType type, Properties parameters) {
if ( parameters.getProperty( EnumType.ENUM ) != null ) {
typeDefinition.setParameter( EnumType.ENUM, parameters.getProperty( EnumType.ENUM ) );
}
else {
typeDefinition.setParameter( EnumType.ENUM, type.getEnumClass().getName() );
}
if ( parameters.getProperty( EnumType.NAMED ) != null ) {
typeDefinition.setParameter( EnumType.NAMED, parameters.getProperty( EnumType.NAMED ) );
}
else {
typeDefinition.setParameter( EnumType.NAMED, Boolean.toString( !type.isOrdinal() ) );
}
}
private boolean isAddNestedType(Value value) {
if ( value instanceof SimpleValue simpleValue ) {
return simpleValue.getTypeParameters() != null;
@ -99,19 +82,12 @@ public final class BasicMetadataGenerator {
final TypeSpecification typeSpecification = new TypeSpecification( typeName );
attribute.setType( typeSpecification );
Type type = value.getType();
if ( type instanceof CustomType && ((CustomType<?>) type).getUserType() instanceof EnumType ) {
// Proper handling of nasty legacy EnumType
mapEnumerationType( typeSpecification, (EnumType) ((CustomType<?>) type).getUserType(), typeParameters );
}
else {
// By default, copying all Hibernate properties
for ( Object object : typeParameters.keySet() ) {
final String keyType = (String) object;
final String property = typeParameters.getProperty( keyType );
if ( property != null ) {
typeSpecification.setParameter( keyType, property );
}
// By default, copying all Hibernate properties
for ( Object object : typeParameters.keySet() ) {
final String keyType = (String) object;
final String property = typeParameters.getProperty( keyType );
if ( property != null ) {
typeSpecification.setParameter( keyType, property );
}
}
}

View File

@ -0,0 +1,333 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.envers.test.integration.customtype;
import jakarta.persistence.Enumerated;
import jakarta.persistence.MapKeyEnumerated;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.annotations.Nationalized;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.type.spi.TypeConfigurationAware;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.LoggableUserType;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import static jakarta.persistence.EnumType.ORDINAL;
import static jakarta.persistence.EnumType.STRING;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
/**
* Value type mapper for enumerations.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
* @author Steve Ebersole
*
* @deprecated Use the built-in support for enums
*/
@Deprecated(since="6.2", forRemoval=true)
public class EnumType<T extends Enum<T>>
implements EnhancedUserType<T>, DynamicParameterizedType, LoggableUserType, TypeConfigurationAware, Serializable {
public static final String ENUM = "enumClass";
public static final String NAMED = "useNamed";
public static final String TYPE = "type";
private Class<T> enumClass;
private boolean isOrdinal;
private JdbcType jdbcType;
private EnumJavaType<T> enumJavaType;
private TypeConfiguration typeConfiguration;
public EnumType() {
}
public Class<T> getEnumClass() {
return enumClass;
}
@Override
public JdbcType getJdbcType(TypeConfiguration typeConfiguration) {
return jdbcType;
}
/**
* <p>
* An instance of this class is "configured" by a call to {@link #setParameterValues},
* where configuration parameters are given as entries in a {@link Properties} object.
* There are two distinct ways an instance may be configured:
* <ul>
* <li>one for {@code hbm.xml}-based mapping, and
* <li>another for annotation-based or {@code orm.xml}-based mapping.
* </ul>
* <p>
* In the case of annotations or {@code orm.xml}, a {@link ParameterType} is passed to
* {@link #setParameterValues} under the key {@value #PARAMETER_TYPE}.
* <p>
* But in the case of {@code hbm.xml}, there are multiple parameters:
* <ul>
* <li>
* {@value #ENUM}, the name of the Java enumeration class.
* </li>
* <li>
* {@value #NAMED}, specifies if the enum should be mapped by name.
* Default is to map as ordinal.
* </li>
* <li>
* {@value #TYPE}, a JDBC type code (legacy alternative to {@value #NAMED}).
* </li>
* </ul>
*/
@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 );
if ( parameters.containsKey( ENUM ) ) {
final String enumClassName = (String) parameters.get( ENUM );
try {
enumClass = (Class<T>) ReflectHelper.classForName( enumClassName, this.getClass() ).asSubclass( Enum.class );
}
catch ( ClassNotFoundException exception ) {
throw new HibernateException("Enum class not found: " + enumClassName, exception);
}
}
else if ( reader != null ) {
enumClass = (Class<T>) reader.getReturnedClass().asSubclass( Enum.class );
}
final JavaType<T> descriptor = typeConfiguration.getJavaTypeRegistry().getDescriptor( enumClass );
enumJavaType = (EnumJavaType<T>) descriptor;
if ( parameters.containsKey( TYPE ) ) {
int jdbcTypeCode = Integer.parseInt( (String) parameters.get( TYPE ) );
jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( jdbcTypeCode );
isOrdinal = jdbcType.isInteger()
// Both, ENUM and NAMED_ENUM are treated like ordinal with respect to the ordering
|| jdbcType.getDefaultSqlTypeCode() == SqlTypes.ENUM
|| jdbcType.getDefaultSqlTypeCode() == SqlTypes.NAMED_ENUM;
}
else {
final LocalJdbcTypeIndicators indicators;
final Long columnLength = reader == null ? null : reader.getColumnLengths()[0];
if ( parameters.containsKey(NAMED) ) {
indicators = new LocalJdbcTypeIndicators(
// use ORDINAL as default for hbm.xml mappings
getBoolean( NAMED, parameters ) ? STRING : ORDINAL,
false,
columnLength
);
}
else {
indicators = new LocalJdbcTypeIndicators(
getEnumType( reader ),
isNationalized( reader ),
columnLength
);
}
jdbcType = descriptor.getRecommendedJdbcType( indicators );
isOrdinal = indicators.getEnumeratedType() != STRING;
}
}
private jakarta.persistence.EnumType getEnumType(ParameterType reader) {
if ( reader != null ) {
if ( reader.isPrimaryKey() ) {
final MapKeyEnumerated enumAnn = getAnnotation( reader.getAnnotationsMethod(), MapKeyEnumerated.class );
if ( enumAnn != null ) {
return enumAnn.value();
}
}
final Enumerated enumAnn = getAnnotation( reader.getAnnotationsMethod(), Enumerated.class );
if ( enumAnn != null ) {
return enumAnn.value();
}
}
return ORDINAL;
}
private boolean isNationalized(ParameterType reader) {
return typeConfiguration.getCurrentBaseSqlTypeIndicators().isNationalized()
|| reader!=null && getAnnotation( reader.getAnnotationsMethod(), Nationalized.class ) != null;
}
@SuppressWarnings("unchecked")
private <A extends Annotation> A getAnnotation(Annotation[] annotations, Class<A> annotationType) {
for ( Annotation annotation : annotations ) {
if ( annotationType.isInstance( annotation ) ) {
return (A) annotation;
}
}
return null;
}
@Override
public int getSqlType() {
verifyConfigured();
return jdbcType.getJdbcTypeCode();
}
@Override
public Class<T> returnedClass() {
return enumClass;
}
@Override
public boolean equals(T x, T y) throws HibernateException {
return x == y;
}
@Override
public int hashCode(T x) throws HibernateException {
return x == null ? 0 : x.hashCode();
}
@Override
public T nullSafeGet(ResultSet rs, int position, WrapperOptions options)
throws SQLException {
verifyConfigured();
return jdbcType.getExtractor( enumJavaType ).extract( rs, position, options );
}
private void verifyConfigured() {
if ( enumJavaType == null ) {
throw new AssertionFailure("EnumType (" + enumClass.getName() + ") not properly, fully configured");
}
}
@Override
public void nullSafeSet(PreparedStatement st, T value, int index, WrapperOptions options)
throws SQLException {
verifyConfigured();
jdbcType.getBinder( enumJavaType ).bind( st, value, index, options );
}
@Override
public T deepCopy(T value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(T value) throws HibernateException {
return value;
}
@Override
public T assemble(Serializable cached, Object owner) throws HibernateException {
return (T) cached;
}
@Override
public T replace(T original, T target, Object owner) throws HibernateException {
return original;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public void setTypeConfiguration(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
@Override
public String toSqlLiteral(T value) {
verifyConfigured();
return isOrdinal()
? Integer.toString( value.ordinal() )
: "'" + value.name() + "'";
}
@Override
public String toString(T value) {
verifyConfigured();
return enumJavaType.toName( value );
}
@Override
public T fromStringValue(CharSequence sequence) {
verifyConfigured();
return enumJavaType.fromName( sequence.toString() );
}
@Override @SuppressWarnings("unchecked")
public String toLoggableString(Object value, SessionFactoryImplementor factory) {
verifyConfigured();
return enumJavaType.extractLoggableRepresentation( (T) value );
}
public boolean isOrdinal() {
verifyConfigured();
return isOrdinal;
}
private class LocalJdbcTypeIndicators implements JdbcTypeIndicators {
private final jakarta.persistence.EnumType enumType;
private final boolean nationalized;
private final Long columnLength;
private LocalJdbcTypeIndicators(jakarta.persistence.EnumType enumType, boolean nationalized, Long columnLength) {
this.enumType = enumType;
this.nationalized = nationalized;
this.columnLength = columnLength;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public jakarta.persistence.EnumType getEnumeratedType() {
return enumType != null ? enumType : typeConfiguration.getCurrentBaseSqlTypeIndicators().getEnumeratedType();
}
@Override
public boolean isNationalized() {
return nationalized;
}
@Override
public long getColumnLength() {
return columnLength == null ? NO_COLUMN_LENGTH : columnLength;
}
@Override
public Dialect getDialect() {
return typeConfiguration.getCurrentBaseSqlTypeIndicators().getDialect();
}
}
}

View File

@ -31,11 +31,10 @@ import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Tests that a custom type which extends {@link org.hibernate.type.EnumType} continues to be
* recognized as an EnumType rather than a basic custom type implementation since the values
* Tests that a custom type which extends {@link org.hibernate.envers.test.integration.customtype.EnumType}
* continues to be recognized as an EnumType rather than a basic custom type implementation since the values
* which envers sends to describe the type in HBM differ whether its an Enum or not.
*
* Without the fix, this test would not even bootstrap and would throw a MappingException.
@ -47,7 +46,7 @@ public class ExtendedEnumTypeTest extends BaseEnversJPAFunctionalTestCase {
// An extended type to trigger the need for Envers to supply type information in the HBM mappings.
// This should be treated the same as any other property annotated as Enumerated or uses an Enum.
public static class ExtendedEnumType extends org.hibernate.type.EnumType<Widget.Status> {
public static class ExtendedEnumType extends org.hibernate.envers.test.integration.customtype.EnumType<Widget.Status> {
}
@ -176,16 +175,17 @@ public class ExtendedEnumTypeTest extends BaseEnversJPAFunctionalTestCase {
final UserType userType = ( (CustomType<Object>) propertyType ).getUserType();
assertTyping( typeClass, userType );
assertTyping( org.hibernate.type.EnumType.class, userType );
assertTyping( org.hibernate.envers.test.integration.customtype.EnumType.class, userType );
switch ( expectedType ) {
case STRING:
assertTrue( !( (org.hibernate.type.EnumType) userType ).isOrdinal() );
break;
default:
assertTrue( ( (org.hibernate.type.EnumType) userType ).isOrdinal() );
break;
}
// org,hibernate.type.EnumType used to be special-cased in the Envers code
// switch ( expectedType ) {
// case STRING:
// assertTrue( !( (org.hibernate.envers.test.integration.customtype.EnumType) userType ).isOrdinal() );
// break;
// default:
// assertTrue( ( (org.hibernate.envers.test.integration.customtype.EnumType) userType ).isOrdinal() );
// break;
// }
} );
}
}

View File

@ -12,14 +12,14 @@
<generator class="increment" />
</id>
<property name="enum1">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.envers.test.integration.customtype.EnumType">
<!-- We omit choice between named and ordinal. -->
<!--<param name="useNamed">true</param>-->
<param name="enumClass">org.hibernate.orm.test.envers.entities.customtype.UnspecifiedEnumTypeEntity$E1</param>
</type>
</property>
<property name="enum2">
<type name="org.hibernate.type.EnumType">
<type name="org.hibernate.envers.test.integration.customtype.EnumType">
<!-- We omit choice between named and ordinal. -->
<!--<param name="useNamed">false</param>-->
<param name="enumClass">org.hibernate.orm.test.envers.entities.customtype.UnspecifiedEnumTypeEntity$E2</param>

View File

@ -6,7 +6,6 @@ package org.hibernate.graalvm.internal;
import org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor;
import org.hibernate.type.EnumType;
/**
* The place to list all "static" types we know of that need to be possible to
@ -36,9 +35,7 @@ final class StaticClassLists {
org.hibernate.id.enhanced.SequenceStyleGenerator.class,
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl.class,
org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl.class,
EnumType.class,
MultiLineSqlScriptExtractor.class,
};
}

View File

@ -114,7 +114,6 @@ public class StaticClassListsTest {
org.hibernate.id.enhanced.SequenceStyleGenerator.class,
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl.class,
org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl.class,
org.hibernate.type.EnumType.class,
org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor.class
);
}