HHH-17884 Respect ordering guarantee of ORDINAL/STRING when using native enums

This commit is contained in:
Christian Beikov 2024-03-28 15:10:57 +01:00
parent 0709709c97
commit f3fca1d6fe
3 changed files with 51 additions and 3 deletions

View File

@ -25,8 +25,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import static java.util.Arrays.sort;
import static java.util.Collections.emptySet;
import static org.hibernate.type.SqlTypes.NAMED_ENUM;
import static org.hibernate.type.descriptor.converter.internal.EnumHelper.getEnumeratedValues;
/**
* Represents a named {@code enum} type on PostgreSQL.
@ -120,9 +122,21 @@ public class PostgreSQLEnumJdbcType implements JdbcType {
Size columnSize,
Database database,
TypeConfiguration typeConfiguration) {
//sort alphabetically, to guarantee alphabetical ordering in queries with 'order by'
addAuxiliaryDatabaseObjects( javaType, database, true );
}
private void addAuxiliaryDatabaseObjects(
JavaType<?> javaType,
Database database,
boolean sortEnumValues) {
final Dialect dialect = database.getDialect();
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType.getJavaType();
final String[] create = dialect.getCreateEnumTypeCommand( enumClass );
String[] values = getEnumeratedValues( enumClass );
if ( sortEnumValues ) {
sort( values );
}
final String[] create = dialect.getCreateEnumTypeCommand( enumClass.getSimpleName(), values );
final String[] drop = dialect.getDropEnumTypeCommand( enumClass );
if ( create != null && create.length>0 ) {
database.addAuxiliaryDatabaseObject(

View File

@ -6,10 +6,33 @@
*/
package org.hibernate.type.descriptor.converter.internal;
import java.util.Arrays;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* @author Gavin King
*/
public class EnumHelper {
public static String[] getEnumeratedValues(Type type) {
return getEnumeratedValues( type.getReturnedClass(), ( (BasicType<?>) type ).getJdbcType() );
}
public static String[] getEnumeratedValues(Class<?> javaType, JdbcType jdbcType) {
//noinspection unchecked
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) javaType;
final String[] enumValues;
if ( jdbcType.isString() ) {
enumValues = getSortedEnumeratedValues( enumClass );
}
else {
enumValues = getEnumeratedValues( enumClass );
}
return enumValues;
}
public static String[] getEnumeratedValues(Class<? extends Enum<?>> enumClass) {
Enum<?>[] values = enumClass.getEnumConstants();
String[] names = new String[values.length];
@ -18,4 +41,10 @@ public class EnumHelper {
}
return names;
}
public static String[] getSortedEnumeratedValues(Class<? extends Enum<?>> enumClass) {
final String[] names = getEnumeratedValues( enumClass );
Arrays.sort( names );
return names;
}
}

View File

@ -9,6 +9,7 @@ package org.hibernate.type.descriptor.sql.internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.converter.internal.EnumHelper;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.sql.DdlType;
@ -38,9 +39,13 @@ public class NativeEnumDdlTypeImpl implements DdlType {
return ENUM;
}
@Override @SuppressWarnings("unchecked")
@Override
@SuppressWarnings("unchecked")
public String getTypeName(Size columnSize, Type type, DdlTypeRegistry ddlTypeRegistry) {
return dialect.getEnumTypeDeclaration( (Class<? extends Enum<?>>) type.getReturnedClass() );
return dialect.getEnumTypeDeclaration(
type.getReturnedClass().getSimpleName(),
EnumHelper.getEnumeratedValues( type )
);
}
@Override