Skip to content

Commit 488cdd9

Browse files
committed
HHH-17884 Fix the enum value sorting for EnumeratedType.STRING enums
1 parent 781888e commit 488cdd9

File tree

8 files changed

+121
-76
lines changed

8 files changed

+121
-76
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import org.hibernate.type.SqlTypes;
6868
import org.hibernate.type.StandardBasicTypes;
6969
import org.hibernate.type.descriptor.java.JavaType;
70+
import org.hibernate.type.descriptor.jdbc.EnumJdbcType;
7071
import org.hibernate.type.descriptor.jdbc.JdbcType;
7172
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
7273
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
@@ -651,6 +652,8 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
651652
.getDescriptor( Object.class )
652653
)
653654
);
655+
656+
jdbcTypeRegistry.addDescriptor( EnumJdbcType.INSTANCE );
654657
}
655658

656659
@Override

hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import org.hibernate.type.SqlTypes;
7171
import org.hibernate.type.StandardBasicTypes;
7272
import org.hibernate.type.descriptor.java.JavaType;
73+
import org.hibernate.type.descriptor.jdbc.EnumJdbcType;
7374
import org.hibernate.type.descriptor.jdbc.JdbcType;
7475
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
7576
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
@@ -671,7 +672,7 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
671672
)
672673
);
673674

674-
jdbcTypeRegistry.addDescriptor( new MySQLEnumJdbcType() );
675+
jdbcTypeRegistry.addDescriptor( EnumJdbcType.INSTANCE );
675676
}
676677

677678
@Override

hibernate-core/src/main/java/org/hibernate/dialect/MySQLEnumJdbcType.java

+4-68
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,7 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import org.hibernate.type.descriptor.ValueBinder;
10-
import org.hibernate.type.descriptor.ValueExtractor;
11-
import org.hibernate.type.descriptor.WrapperOptions;
12-
import org.hibernate.type.descriptor.java.JavaType;
13-
import org.hibernate.type.descriptor.jdbc.BasicBinder;
14-
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
15-
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
16-
import org.hibernate.type.descriptor.jdbc.JdbcType;
17-
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterCharacterData;
18-
19-
import java.sql.CallableStatement;
20-
import java.sql.PreparedStatement;
21-
import java.sql.ResultSet;
22-
import java.sql.SQLException;
23-
24-
import static org.hibernate.type.SqlTypes.ENUM;
9+
import org.hibernate.type.descriptor.jdbc.EnumJdbcType;
2510

2611
/**
2712
* Represents an {@code enum} type on MySQL.
@@ -31,60 +16,11 @@
3116
*
3217
* @see org.hibernate.type.SqlTypes#ENUM
3318
* @see MySQLDialect#getEnumTypeDeclaration(String, String[])
19+
* @deprecated Use {@link EnumJdbcType} instead
3420
*
3521
* @author Gavin King
3622
*/
37-
public class MySQLEnumJdbcType implements JdbcType {
38-
39-
@Override
40-
public int getJdbcTypeCode() {
41-
return ENUM;
42-
}
43-
44-
@Override
45-
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
46-
return new JdbcLiteralFormatterCharacterData<>( javaType );
47-
}
48-
49-
@Override
50-
public String getFriendlyName() {
51-
return "ENUM";
52-
}
53-
54-
@Override
55-
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
56-
return new BasicBinder<>( javaType, this ) {
57-
@Override
58-
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
59-
throws SQLException {
60-
st.setString( index, getJavaType().unwrap( value, String.class, options ) );
61-
}
62-
63-
@Override
64-
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
65-
throws SQLException {
66-
st.setString( name, getJavaType().unwrap( value, String.class, options ) );
67-
}
68-
};
69-
}
70-
71-
@Override
72-
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
73-
return new BasicExtractor<>( javaType, this ) {
74-
@Override
75-
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
76-
return getJavaType().wrap( rs.getString( paramIndex ), options );
77-
}
78-
79-
@Override
80-
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
81-
return getJavaType().wrap( statement.getString( index ), options );
82-
}
23+
@Deprecated
24+
public class MySQLEnumJdbcType extends EnumJdbcType {
8325

84-
@Override
85-
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
86-
return getJavaType().wrap( statement.getString( name ), options );
87-
}
88-
};
89-
}
9026
}

hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLEnumJdbcType.java

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static java.util.Arrays.sort;
2929
import static java.util.Collections.emptySet;
3030
import static org.hibernate.type.SqlTypes.NAMED_ENUM;
31+
import static org.hibernate.type.SqlTypes.OTHER;
3132
import static org.hibernate.type.descriptor.converter.internal.EnumHelper.getEnumeratedValues;
3233

3334
/**
@@ -50,6 +51,11 @@ public class PostgreSQLEnumJdbcType implements JdbcType {
5051

5152
@Override
5253
public int getJdbcTypeCode() {
54+
return OTHER;
55+
}
56+
57+
@Override
58+
public int getDefaultSqlTypeCode() {
5359
return NAMED_ENUM;
5460
}
5561

hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/EnumHelper.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Arrays;
1010

1111
import org.hibernate.type.BasicType;
12+
import org.hibernate.type.SqlTypes;
1213
import org.hibernate.type.Type;
1314
import org.hibernate.type.descriptor.jdbc.JdbcType;
1415

@@ -24,11 +25,14 @@ public static String[] getEnumeratedValues(Class<?> javaType, JdbcType jdbcType)
2425
//noinspection unchecked
2526
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType;
2627
final String[] enumValues;
27-
if ( jdbcType.isString() ) {
28-
enumValues = getSortedEnumeratedValues( enumClass );
29-
}
30-
else {
31-
enumValues = getEnumeratedValues( enumClass );
28+
switch ( jdbcType.getDefaultSqlTypeCode() ) {
29+
case SqlTypes.ENUM:
30+
case SqlTypes.NAMED_ENUM:
31+
enumValues = getSortedEnumeratedValues( enumClass );
32+
break;
33+
default:
34+
enumValues = getEnumeratedValues( enumClass );
35+
break;
3236
}
3337
return enumValues;
3438
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.type.descriptor.jdbc;
8+
9+
import java.sql.CallableStatement;
10+
import java.sql.PreparedStatement;
11+
import java.sql.ResultSet;
12+
import java.sql.SQLException;
13+
14+
import org.hibernate.dialect.MySQLDialect;
15+
import org.hibernate.type.descriptor.ValueBinder;
16+
import org.hibernate.type.descriptor.ValueExtractor;
17+
import org.hibernate.type.descriptor.WrapperOptions;
18+
import org.hibernate.type.descriptor.java.JavaType;
19+
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterCharacterData;
20+
21+
import static org.hibernate.type.SqlTypes.ENUM;
22+
import static org.hibernate.type.SqlTypes.VARCHAR;
23+
24+
/**
25+
* Represents an {@code enum} type for databases like MySQL and H2.
26+
* <p>
27+
* Hibernate will automatically use this for enums mapped
28+
* as {@link jakarta.persistence.EnumType#STRING}.
29+
*
30+
* @see org.hibernate.type.SqlTypes#ENUM
31+
* @see MySQLDialect#getEnumTypeDeclaration(String, String[])
32+
*
33+
* @author Gavin King
34+
*/
35+
public class EnumJdbcType implements JdbcType {
36+
37+
public static final EnumJdbcType INSTANCE = new EnumJdbcType();
38+
39+
@Override
40+
public int getJdbcTypeCode() {
41+
return VARCHAR;
42+
}
43+
44+
@Override
45+
public int getDefaultSqlTypeCode() {
46+
return ENUM;
47+
}
48+
49+
@Override
50+
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
51+
return new JdbcLiteralFormatterCharacterData<>( javaType );
52+
}
53+
54+
@Override
55+
public String getFriendlyName() {
56+
return "ENUM";
57+
}
58+
59+
@Override
60+
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
61+
return new BasicBinder<>( javaType, this ) {
62+
@Override
63+
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
64+
throws SQLException {
65+
st.setString( index, getJavaType().unwrap( value, String.class, options ) );
66+
}
67+
68+
@Override
69+
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
70+
throws SQLException {
71+
st.setString( name, getJavaType().unwrap( value, String.class, options ) );
72+
}
73+
};
74+
}
75+
76+
@Override
77+
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
78+
return new BasicExtractor<>( javaType, this ) {
79+
@Override
80+
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
81+
return getJavaType().wrap( rs.getString( paramIndex ), options );
82+
}
83+
84+
@Override
85+
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
86+
return getJavaType().wrap( statement.getString( index ), options );
87+
}
88+
89+
@Override
90+
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
91+
return getJavaType().wrap( statement.getString( name ), options );
92+
}
93+
};
94+
}
95+
}

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/EnumeratedSmokeTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private void validateEnumMapping(JdbcTypeRegistry jdbcRegistry, Property propert
6767
}
6868
else {
6969
// Assertions.assertThat( valueConverter ).isInstanceOf( NamedEnumValueConverter.class );
70-
Assertions.assertThat(jdbcType.isString() || jdbcType.getJdbcTypeCode() == SqlTypes.ENUM).isTrue();
70+
Assertions.assertThat( jdbcType.isString() || jdbcType.getDefaultSqlTypeCode() == SqlTypes.ENUM ).isTrue();
7171
}
7272
}
7373

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/ormXml/OrmXmlEnumTypeTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public void testOrmXmlDefinedEnumType() {
4848
BasicTypeImpl<?> enumMapping = ExtraAssertions.assertTyping( BasicTypeImpl.class, bindingPropertyType );
4949
assertEquals(
5050
jdbcTypeRegistry.getDescriptor( jdbcTypeRegistry.hasRegisteredDescriptor( ENUM ) ? ENUM : VARCHAR ),
51-
jdbcTypeRegistry.getDescriptor( enumMapping.getJdbcType().getJdbcTypeCode() )
51+
jdbcTypeRegistry.getDescriptor( enumMapping.getJdbcType().getDefaultSqlTypeCode() )
5252
);
5353
}
5454
finally {

0 commit comments

Comments
 (0)