HHH-16317 Don't use InstantAsTimestampWithTimeZoneJdbcType for PG-JDBC and MSSQL due to a bug
This commit is contained in:
parent
41bec6d5f9
commit
eb9e16c83f
|
@ -72,7 +72,6 @@ import org.hibernate.sql.ast.tree.Statement;
|
|||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsOffsetDateTimeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
|
@ -334,7 +333,8 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
protected void contributeCockroachTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
|
||||
.getJdbcTypeRegistry();
|
||||
jdbcTypeRegistry.addDescriptor( TIMESTAMP_UTC, TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
|
||||
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
|
||||
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
|
||||
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
|
||||
|
|
|
@ -91,7 +91,6 @@ import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
|||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsOffsetDateTimeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
|
@ -108,9 +107,6 @@ import jakarta.persistence.TemporalType;
|
|||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.EPOCH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.MONTH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.QUARTER;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
|
||||
import static org.hibernate.type.SqlTypes.ARRAY;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
import static org.hibernate.type.SqlTypes.BLOB;
|
||||
|
@ -1331,7 +1327,8 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
// dialect uses oid for Blobs, byte arrays cannot be used.
|
||||
jdbcTypeRegistry.addDescriptor( Types.BLOB, BlobJdbcType.BLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcType.CLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( TIMESTAMP_UTC, TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
|
||||
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );
|
||||
|
||||
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.hibernate.type.BasicTypeRegistry;
|
|||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsJdbcTimestampJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntAsSmallIntJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
||||
|
@ -267,6 +268,9 @@ public class SQLServerLegacyDialect extends AbstractTransactSQLDialect {
|
|||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.contributeTypes( typeContributions, serviceRegistry );
|
||||
|
||||
// Need to bind as java.sql.Timestamp because reading OffsetDateTime from a "datetime2" column fails
|
||||
typeContributions.contributeJdbcType( TimestampUtcAsJdbcTimestampJdbcType.INSTANCE );
|
||||
|
||||
typeContributions.getTypeConfiguration().getJdbcTypeRegistry().addDescriptor(
|
||||
Types.TINYINT,
|
||||
TinyIntAsSmallIntJdbcType.INSTANCE
|
||||
|
|
|
@ -59,7 +59,6 @@ import org.hibernate.sql.ast.tree.Statement;
|
|||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsOffsetDateTimeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
|
@ -79,7 +78,6 @@ import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtract
|
|||
import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.EPOCH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
|
||||
import static org.hibernate.type.SqlTypes.ARRAY;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
import static org.hibernate.type.SqlTypes.BLOB;
|
||||
|
@ -354,7 +352,8 @@ public class CockroachDialect extends Dialect {
|
|||
protected void contributeCockroachTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
|
||||
.getJdbcTypeRegistry();
|
||||
jdbcTypeRegistry.addDescriptor( TIMESTAMP_UTC, TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
|
||||
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
|
||||
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
|
||||
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
|
||||
|
|
|
@ -80,7 +80,6 @@ import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
|||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsOffsetDateTimeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
|
@ -97,9 +96,6 @@ import jakarta.persistence.TemporalType;
|
|||
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.EPOCH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.MONTH;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.QUARTER;
|
||||
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
|
||||
import static org.hibernate.type.SqlTypes.ARRAY;
|
||||
import static org.hibernate.type.SqlTypes.BINARY;
|
||||
import static org.hibernate.type.SqlTypes.BLOB;
|
||||
|
@ -1339,7 +1335,8 @@ public class PostgreSQLDialect extends Dialect {
|
|||
// dialect uses oid for Blobs, byte arrays cannot be used.
|
||||
jdbcTypeRegistry.addDescriptor( Types.BLOB, BlobJdbcType.BLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcType.CLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( TIMESTAMP_UTC, TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
|
||||
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
|
||||
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );
|
||||
|
||||
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
|
||||
|
|
|
@ -73,6 +73,7 @@ import org.hibernate.type.BasicTypeRegistry;
|
|||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsJdbcTimestampJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntAsSmallIntJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
||||
|
@ -274,6 +275,9 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.contributeTypes( typeContributions, serviceRegistry );
|
||||
|
||||
// Need to bind as java.sql.Timestamp because reading OffsetDateTime from a "datetime2" column fails
|
||||
typeContributions.contributeJdbcType( TimestampUtcAsJdbcTimestampJdbcType.INSTANCE );
|
||||
|
||||
typeContributions.getTypeConfiguration().getJdbcTypeRegistry().addDescriptor(
|
||||
Types.TINYINT,
|
||||
TinyIntAsSmallIntJdbcType.INSTANCE
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.hibernate.testing.jdbc.SharedDriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@DomainModel(
|
||||
annotatedClasses = { InstantTimestampWithoutTimezoneTest.SomeEntity.class }
|
||||
)
|
||||
@SessionFactory
|
||||
@JiraKey( "HHH-16317" )
|
||||
public class InstantTimestampWithoutTimezoneTest {
|
||||
|
||||
@Test
|
||||
@Disabled("Just for local testing")
|
||||
public void testJdbc(SessionFactoryScope scope) {
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault( TimeZone.getTimeZone( "GMT+1" ) );
|
||||
SharedDriverManagerConnectionProviderImpl.getInstance().reset();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.doWork(
|
||||
connection -> {
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(
|
||||
"insert into SOMEENTITY (ID,TSDATA) values (1,?)" )) {
|
||||
preparedStatement.setObject(
|
||||
1,
|
||||
OffsetDateTime.parse( "2020-01-01T12:00:00Z" )
|
||||
);
|
||||
preparedStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.doWork(
|
||||
connection -> {
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(
|
||||
"select e.TSDATA from SOMEENTITY e where e.ID=1" );
|
||||
ResultSet resultSet = preparedStatement.executeQuery()) {
|
||||
resultSet.next();
|
||||
OffsetDateTime offsetDateTime = resultSet.getObject( 1, OffsetDateTime.class );
|
||||
assertEquals(
|
||||
OffsetDateTime.parse( "2020-01-01T12:00:00Z" ).toInstant(),
|
||||
offsetDateTime.toInstant()
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
TimeZone.setDefault( timeZone );
|
||||
SharedDriverManagerConnectionProviderImpl.getInstance().reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNativeQuery(SessionFactoryScope scope) {
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault( TimeZone.getTimeZone( "GMT+1" ) );
|
||||
SharedDriverManagerConnectionProviderImpl.getInstance().reset();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createNativeMutationQuery( "insert into SOMEENTITY (ID,TSDATA) values (2,?)" )
|
||||
.setParameter( 1, OffsetDateTime.parse( "2020-01-01T12:00:00Z" ).toInstant() )
|
||||
.executeUpdate();
|
||||
final Instant instant = session.createNativeQuery(
|
||||
"select e.TSDATA from SOMEENTITY e where e.ID=2",
|
||||
Instant.class
|
||||
).getSingleResult();
|
||||
assertEquals(
|
||||
OffsetDateTime.parse( "2020-01-01T12:00:00Z" ).toInstant(),
|
||||
instant
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
TimeZone.setDefault( timeZone );
|
||||
SharedDriverManagerConnectionProviderImpl.getInstance().reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "SOMEENTITY")
|
||||
@Access(AccessType.FIELD)
|
||||
public static class SomeEntity {
|
||||
@Id
|
||||
@Column(name = "ID")
|
||||
private Integer id;
|
||||
@Column(name = "TSDATA")
|
||||
private java.sql.Timestamp tsData;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue