HHH-16125 fix enums in embeddable types on postgres

fixes allowing correct serialization/deserialization of enums
includes workaround for StructJdbcType sending us a BigDecimal (need better solution)
This commit is contained in:
Gavin 2023-04-28 14:45:43 +02:00 committed by Gavin King
parent db4a1bb6ef
commit 9c6c3eba81
4 changed files with 33 additions and 7 deletions

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.dialect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -24,7 +22,6 @@ import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.TimeZone;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.internal.util.CharSequenceHelper;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
@ -33,16 +30,14 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StringBuilderSqlAppender;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.IntegerJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType;
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.spi.TypeConfiguration;
@ -492,6 +487,14 @@ public abstract class AbstractPostgreSQLStructJdbcType implements AggregateJdbcT
options
);
}
else if ( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass().isEnum()
&& jdbcMapping.getJdbcType().isInteger() ) {
values[column] = fromRawObject(
jdbcMapping,
IntegerJavaType.INSTANCE.fromEncodedString( string, start, i ),
options
);
}
else {
values[column] = fromString(
jdbcMapping,
@ -761,6 +764,10 @@ public abstract class AbstractPostgreSQLStructJdbcType implements AggregateJdbcT
appender.append( (Boolean) subValue ? '1' : '0' );
break;
}
if ( subValue instanceof Enum ) {
appender.appendSql( ((Enum<?>) subValue).ordinal() );
break;
}
case SqlTypes.BOOLEAN:
case SqlTypes.BIT:
case SqlTypes.BIGINT:
@ -791,6 +798,7 @@ public abstract class AbstractPostgreSQLStructJdbcType implements AggregateJdbcT
case SqlTypes.LONGNVARCHAR:
case SqlTypes.LONG32VARCHAR:
case SqlTypes.LONG32NVARCHAR:
case SqlTypes.ENUM:
appender.quoteStart();
jdbcJavaType.appendEncodedString(
appender,

View File

@ -123,6 +123,10 @@ public class JsonHelper {
appender.append( (Boolean) value ? '1' : '0' );
break;
}
if ( value instanceof Enum ) {
appender.appendSql( ((Enum<?>) value).ordinal() );
break;
}
case SqlTypes.BOOLEAN:
case SqlTypes.BIT:
case SqlTypes.BIGINT:
@ -147,6 +151,7 @@ public class JsonHelper {
case SqlTypes.LONGNVARCHAR:
case SqlTypes.LONG32VARCHAR:
case SqlTypes.LONG32NVARCHAR:
case SqlTypes.ENUM:
// These literals can contain the '"' character, so we need to escape it
appender.append( '"' );
appender.startEscaping();
@ -830,10 +835,14 @@ public class JsonHelper {
case SqlTypes.TINYINT:
case SqlTypes.SMALLINT:
case SqlTypes.INTEGER:
if ( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass() == Boolean.class ) {
Class<?> javaTypeClass = jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass();
if ( javaTypeClass == Boolean.class ) {
// BooleanJavaType has this as an implicit conversion
return Integer.parseInt( string, start , end, 10 ) == 1;
}
if ( javaTypeClass.isEnum() ) {
return javaTypeClass.getEnumConstants()[Integer.parseInt( string, start , end, 10 )];
}
case SqlTypes.CHAR:
case SqlTypes.NCHAR:
case SqlTypes.VARCHAR:

View File

@ -26,6 +26,7 @@ import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.IntegerJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.JdbcDateJavaType;
import org.hibernate.type.descriptor.java.JdbcTimeJavaType;
@ -142,6 +143,11 @@ public class XmlHelper {
case SqlTypes.DOUBLE:
case SqlTypes.DECIMAL:
case SqlTypes.NUMERIC:
Class<?> javaTypeClass = jdbcMapping.getMappedJavaType().getJavaTypeClass();
if ( javaTypeClass.isEnum() ) {
return javaTypeClass.getEnumConstants()
[IntegerJavaType.INSTANCE.fromEncodedString( string, start, end )];
}
return fromString(
jdbcMapping,
string,

View File

@ -116,6 +116,9 @@ public class EnumJavaType<T extends Enum<T>> extends AbstractClassJavaType<T> {
else if ( value instanceof Byte ) {
return fromByte( (Byte) value );
}
else if ( value instanceof Number ) {
return fromLong( ((Number) value).longValue() );
}
return (T) value;
}