HHH-17246 - Guard against Sybase being configured for truncating trailing zeros
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
ab9eb9a496
commit
532d5460d4
|
@ -90,6 +90,7 @@ import org.hibernate.type.descriptor.jdbc.JsonAsStringJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.XmlArrayJdbcTypeConstructor;
|
import org.hibernate.type.descriptor.jdbc.XmlArrayJdbcTypeConstructor;
|
||||||
import org.hibernate.type.descriptor.jdbc.XmlAsStringArrayJdbcTypeConstructor;
|
import org.hibernate.type.descriptor.jdbc.XmlAsStringArrayJdbcTypeConstructor;
|
||||||
import org.hibernate.type.descriptor.jdbc.XmlAsStringJdbcType;
|
import org.hibernate.type.descriptor.jdbc.XmlAsStringJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.UuidAsBinaryJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.DdlType;
|
import org.hibernate.type.descriptor.sql.DdlType;
|
||||||
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
||||||
|
@ -752,7 +753,7 @@ public class MetadataBuildingProcess {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addFallbackIfNecessary( jdbcTypeRegistry, SqlTypes.UUID, SqlTypes.BINARY );
|
jdbcTypeRegistry.addDescriptorIfAbsent( UuidAsBinaryJdbcType.INSTANCE );
|
||||||
}
|
}
|
||||||
|
|
||||||
jdbcTypeRegistry.addDescriptorIfAbsent( JsonAsStringJdbcType.VARCHAR_INSTANCE );
|
jdbcTypeRegistry.addDescriptorIfAbsent( JsonAsStringJdbcType.VARCHAR_INSTANCE );
|
||||||
|
|
|
@ -82,6 +82,7 @@ import org.hibernate.tool.schema.spi.Exporter;
|
||||||
import org.hibernate.type.JavaObjectType;
|
import org.hibernate.type.JavaObjectType;
|
||||||
import org.hibernate.type.NullType;
|
import org.hibernate.type.NullType;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.descriptor.java.OracleUUIDJavaType;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
@ -1041,6 +1042,8 @@ public class OracleDialect extends Dialect {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typeContributions.contributeJavaType( OracleUUIDJavaType.INSTANCE );
|
||||||
|
|
||||||
if(getVersion().isSameOrAfter(23)) {
|
if(getVersion().isSameOrAfter(23)) {
|
||||||
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
|
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
|
||||||
jdbcTypeRegistry.addDescriptor(OracleEnumJdbcType.INSTANCE);
|
jdbcTypeRegistry.addDescriptor(OracleEnumJdbcType.INSTANCE);
|
||||||
|
|
|
@ -64,6 +64,7 @@ import static org.hibernate.type.SqlTypes.TIMESTAMP;
|
||||||
import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
|
import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
|
||||||
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
|
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
|
||||||
import static org.hibernate.type.SqlTypes.TINYINT;
|
import static org.hibernate.type.SqlTypes.TINYINT;
|
||||||
|
import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
|
|
||||||
public class OracleAggregateSupport extends AggregateSupportImpl {
|
public class OracleAggregateSupport extends AggregateSupportImpl {
|
||||||
|
@ -209,6 +210,7 @@ public class OracleAggregateSupport extends AggregateSupportImpl {
|
||||||
case BINARY:
|
case BINARY:
|
||||||
case VARBINARY:
|
case VARBINARY:
|
||||||
case LONG32VARBINARY:
|
case LONG32VARBINARY:
|
||||||
|
case UUID:
|
||||||
return template.replace(
|
return template.replace(
|
||||||
placeholder,
|
placeholder,
|
||||||
jdbcType.getSqlTypeName() + "_from_json(json_query(" + parentPartExpression + columnExpression + "' returning " + jsonTypeName + "))"
|
jdbcType.getSqlTypeName() + "_from_json(json_query(" + parentPartExpression + columnExpression + "' returning " + jsonTypeName + "))"
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.descriptor.java;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jan Schatteman
|
||||||
|
*/
|
||||||
|
public class OracleUUIDJavaType extends UUIDJavaType {
|
||||||
|
|
||||||
|
/* This class is related to the changes that were made for HHH-17246 */
|
||||||
|
|
||||||
|
public static final OracleUUIDJavaType INSTANCE = new OracleUUIDJavaType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(UUID value) {
|
||||||
|
return NoDashesStringTransformer.INSTANCE.transform( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID fromString(CharSequence string) {
|
||||||
|
return NoDashesStringTransformer.INSTANCE.parse( string.toString() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,10 +37,12 @@ public class UUIDJavaType extends AbstractClassJavaType<UUID> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString(UUID value) {
|
public String toString(UUID value) {
|
||||||
return ToStringTransformer.INSTANCE.transform( value );
|
return ToStringTransformer.INSTANCE.transform( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public UUID fromString(CharSequence string) {
|
public UUID fromString(CharSequence string) {
|
||||||
return ToStringTransformer.INSTANCE.parse( string.toString() );
|
return ToStringTransformer.INSTANCE.parse( string.toString() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.descriptor.jdbc;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.hibernate.type.SqlTypes.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jan Schatteman
|
||||||
|
*/
|
||||||
|
public class UuidAsBinaryJdbcType extends BinaryJdbcType {
|
||||||
|
|
||||||
|
public static final UuidAsBinaryJdbcType INSTANCE = new UuidAsBinaryJdbcType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDdlTypeCode() {
|
||||||
|
return Types.BINARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultSqlTypeCode() {
|
||||||
|
return UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor( JavaType<X> javaType ) {
|
||||||
|
return new BasicExtractor<>( javaType, this ) {
|
||||||
|
@Override
|
||||||
|
protected X doExtract( ResultSet rs, int paramIndex, WrapperOptions options ) throws SQLException {
|
||||||
|
final byte[] bytes = rs.getBytes( paramIndex );
|
||||||
|
return javaType.wrap( bytes == null || bytes.length == 16 ? bytes : Arrays.copyOf( bytes, 16 ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract( CallableStatement statement, int index, WrapperOptions options ) throws SQLException {
|
||||||
|
final byte[] bytes = statement.getBytes( index );
|
||||||
|
return javaType.wrap( bytes == null || bytes.length == 16 ? bytes : Arrays.copyOf( bytes, 16 ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract( CallableStatement statement, String name, WrapperOptions options )
|
||||||
|
throws SQLException {
|
||||||
|
final byte[] bytes = statement.getBytes( name );
|
||||||
|
return javaType.wrap( bytes == null || bytes.length == 16 ? bytes : Arrays.copyOf( bytes, 16 ), options );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.id.uuid;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import org.hibernate.annotations.JdbcType;
|
||||||
|
import org.hibernate.dialect.SybaseASEDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.JiraKey;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jan Schatteman
|
||||||
|
*/
|
||||||
|
@RequiresDialect(value = SybaseASEDialect.class)
|
||||||
|
@DomainModel(annotatedClasses = { SybaseASEUUIDTest.Book.class })
|
||||||
|
@SessionFactory
|
||||||
|
public class SybaseASEUUIDTest {
|
||||||
|
|
||||||
|
private static final UUID uuid = UUID.fromString("53886a8a-7082-4879-b430-25cb94415b00");
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
final Book book = new Book(uuid, "John Doe");
|
||||||
|
session.persist( book );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> session.createMutationQuery( "delete from Book" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@JiraKey( value = "HHH-17246" )
|
||||||
|
public void testTrailingZeroByteTruncation(SessionFactoryScope scope) {
|
||||||
|
scope.inSession(
|
||||||
|
session -> assertEquals( 15, session.createNativeQuery("select id from Book", byte[].class).getSingleResult().length )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Book b = session.createQuery( "from Book", Book.class ).getSingleResult();
|
||||||
|
assertEquals(uuid, b.id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Book")
|
||||||
|
static class Book {
|
||||||
|
@Id
|
||||||
|
// The purpose is to effectively provoke the trailing 0 bytes truncation
|
||||||
|
@JdbcType( SybaseUuidAsVarbinaryJdbcType.class )
|
||||||
|
UUID id;
|
||||||
|
|
||||||
|
String author;
|
||||||
|
|
||||||
|
public Book() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Book(UUID id, String author) {
|
||||||
|
this.id = id;
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.id.uuid;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.jdbc.UuidAsBinaryJdbcType;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jan Schatteman
|
||||||
|
*/
|
||||||
|
public class SybaseUuidAsVarbinaryJdbcType extends UuidAsBinaryJdbcType {
|
||||||
|
@Override
|
||||||
|
public int getDdlTypeCode() {
|
||||||
|
return Types.VARBINARY;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue