Implement global configuration and sketch out annotations for time zone storage configuration. Move type tests and add skips for some tests running into H2 bugs. Also, fix some jdbc type assertion tests
This commit is contained in:
parent
597f4bdf6a
commit
548df627e6
|
@ -295,6 +295,20 @@ Assuming `hibernate.globally_quoted_identifiers` is `true`, this allows the glob
|
|||
`*hibernate.auto_quote_keyword*` (e.g. `true` or `false` (default value))::
|
||||
Specifies whether to automatically quote any names that are deemed keywords.
|
||||
|
||||
==== Time zone storage
|
||||
`*hibernate.timezone.default_storage*` (e.g. `COLUMN`, `NATIVE`, `AUTO` or `NORMALIZE` (default value))::
|
||||
Global setting for configuring the default storage for the time zone information for time zone based types.
|
||||
+
|
||||
`NORMALIZE`::: Does not store the time zone, and instead normalizes timestamps to UTC
|
||||
`COLUMN`::: Stores the time zone in a separate column; works in conjunction with `@TimeZoneColumn`
|
||||
`NATIVE`::: Stores the time zone by using the `with time zone` type. Error if `Dialect#getTimeZoneSupport()` is not `NATIVE`
|
||||
`AUTO`::: Stores the time zone either with `NATIVE` if `Dialect#getTimeZoneSupport()` is `NATIVE`, otherwise uses the `COLUMN` strategy.
|
||||
+
|
||||
The default value is given by the {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE},
|
||||
meaning that time zone information is not stored by default, but timestamps are normalized instead.
|
||||
+
|
||||
See the discussion https://github.com/hibernate/hibernate-orm/discussions/4201[on GitHub] for additional background info.
|
||||
|
||||
==== Discriminator options
|
||||
`*hibernate.discriminator.implicit_for_joined*` (e.g. `true` or `false` (default value))::
|
||||
The legacy behavior of Hibernate is to not use discriminators for joined inheritance (Hibernate does not need the discriminator).
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.metamodel.MappingMetamodel;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -41,6 +42,8 @@ public class BigDecimalMappingTests {
|
|||
// first, verify the type selections...
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBigDecimals.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||
|
@ -48,7 +51,7 @@ public class BigDecimalMappingTests {
|
|||
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigDecimal.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.NUMERIC ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( Types.NUMERIC ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.metamodel.MappingMetamodel;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -41,6 +42,8 @@ public class BigIntegerMappingTests {
|
|||
// first, verify the type selections...
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBigIntegers.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||
|
@ -48,7 +51,7 @@ public class BigIntegerMappingTests {
|
|||
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigInteger.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.NUMERIC ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( Types.NUMERIC ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -43,6 +44,8 @@ public class ByteMappingTests {
|
|||
// first, verify the type selections...
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBytes.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||
|
@ -50,7 +53,7 @@ public class ByteMappingTests {
|
|||
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.TINYINT ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( Types.TINYINT ) ) );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -59,7 +62,7 @@ public class ByteMappingTests {
|
|||
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.TINYINT ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( Types.TINYINT ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.metamodel.MappingMetamodel;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
|
@ -29,6 +30,7 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* @see CharacterArrayMappingTests
|
||||
|
@ -43,6 +45,8 @@ public class CharacterArrayNationalizedMappingTests {
|
|||
public void verifyMappings(SessionFactoryScope scope) {
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithCharArrays.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||
|
@ -50,26 +54,26 @@ public class CharacterArrayNationalizedMappingTests {
|
|||
{
|
||||
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveNVarchar" );
|
||||
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() ) ) );
|
||||
}
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperNVarchar" );
|
||||
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() ) ) );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveNClob" );
|
||||
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() ) ) );
|
||||
}
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperNClob" );
|
||||
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -25,6 +26,7 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -37,11 +39,13 @@ public class DurationMappingTests {
|
|||
public void verifyMappings(SessionFactoryScope scope) {
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithDuration.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "duration" );
|
||||
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Duration.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.NUMERIC ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( Types.NUMERIC ) ) );
|
||||
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.userguide.mapping.basic;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
|
@ -18,6 +20,7 @@ import org.hibernate.metamodel.MappingMetamodel;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -27,6 +30,7 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* Tests for mapping `double` values
|
||||
|
@ -42,6 +46,8 @@ public class StringNationalizedMappingTests {
|
|||
// first, verify the type selections...
|
||||
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfStrings.class );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||
|
@ -50,14 +56,14 @@ public class StringNationalizedMappingTests {
|
|||
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "nstring" );
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() ) ) );
|
||||
}
|
||||
|
||||
{
|
||||
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "nclobString" );
|
||||
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||
assertThat( jdbcMapping.getJdbcTypeDescriptor(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.community.dialect.identity.CUBRIDIdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
|
@ -372,8 +373,8 @@ public class CUBRIDDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.dialect.BooleanDecoder;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.query.NullOrdering;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
|
@ -57,11 +58,9 @@ import org.hibernate.type.BasicTypeRegistry;
|
|||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Arrays;
|
||||
|
@ -170,8 +169,8 @@ public class FirebirdDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return getVersion() >= 400;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return getVersion() >= 400 ? TimeZoneSupport.NATIVE : TimeZoneSupport.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -315,7 +314,7 @@ public class FirebirdDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String currentLocalTime() {
|
||||
if ( supportsTimezoneTypes() ) {
|
||||
if ( getTimeZoneSupport() == TimeZoneSupport.NATIVE ) {
|
||||
return "localtime";
|
||||
}
|
||||
else {
|
||||
|
@ -325,7 +324,7 @@ public class FirebirdDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String currentLocalTimestamp() {
|
||||
if ( supportsTimezoneTypes() ) {
|
||||
if ( getTimeZoneSupport() == TimeZoneSupport.NATIVE ) {
|
||||
return "localtimestamp";
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.community.dialect;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.community.dialect.identity.Ingres10IdentityColumnSupport;
|
||||
|
@ -318,8 +319,8 @@ public class IngresDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.hibernate.community.dialect;
|
|||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.dialect.RowLockStrategy;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.community.dialect.identity.SybaseAnywhereIdentityColumnSupport;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
|
@ -80,8 +81,8 @@ public class SybaseAnywhereDialect extends SybaseDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Describes the storage strategies understood by Hibernate.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Incubating
|
||||
public enum TimeZoneStorageStrategy {
|
||||
/**
|
||||
* Stores the time zone through the "with time zone" types which retain the information.
|
||||
*/
|
||||
NATIVE,
|
||||
/**
|
||||
* Stores the time zone in a separate column.
|
||||
*/
|
||||
COLUMN,
|
||||
/**
|
||||
* Doesn't store the time zone, but instead normalizes to UTC.
|
||||
*/
|
||||
NORMALIZE;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
|
||||
/**
|
||||
* Specifies the column name and type to use for storing the time zone information.
|
||||
* The annotation can be used in conjunction with the <code>TimeZoneStorageType.AUTO</code> and
|
||||
* <code>TimeZoneStorageType.COLUMN</code>. The column is simply ignored if <code>TimeZoneStorageType.AUTO</code>
|
||||
* is used and the database supports native time zone storage.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
* @see TimeZoneStorage
|
||||
* @see TimeZoneStorageType#COLUMN
|
||||
* @see TimeZoneStorageType#AUTO
|
||||
*/
|
||||
@Incubating
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ FIELD, METHOD })
|
||||
public @interface TimeZoneColumn {
|
||||
|
||||
/**
|
||||
* The column for the time zone information.
|
||||
*/
|
||||
Column column();
|
||||
|
||||
/**
|
||||
* The storage type for the time zone information.
|
||||
*/
|
||||
TimeZoneType type() default TimeZoneType.OFFSET;
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
|
||||
/**
|
||||
* Specifies how the time zone information of a persistent property or field should be persisted.
|
||||
* The <code>TimeZoneStorage</code> annotation may be used in conjunction with the <code>Basic</code> annotation, or in
|
||||
* conjunction with the <code>ElementCollection</code> annotation when the
|
||||
* element collection value is of basic type. If the <code>TimeZoneStorage</code> annotation is not
|
||||
* used, the <code>TimeZoneStorageType</code> value is assumed to be <code>NORMALIZED</code>.
|
||||
*
|
||||
* <pre>
|
||||
* Example:
|
||||
*
|
||||
* @Entity public class Person {
|
||||
* public OffsetDateTime getBirthDateTimeNormalized() {...}
|
||||
*
|
||||
* @TimeZoneStorage
|
||||
* @TimeZoneColumn(column = @Column(...))
|
||||
* public OffsetDateTime getBirthDateTimeNativeOrColumn() {...}
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Christian Beikov
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
* @see TimeZoneColumn
|
||||
*/
|
||||
@Incubating
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ FIELD, METHOD })
|
||||
public @interface TimeZoneStorage {
|
||||
/**
|
||||
* The storage strategy for the time zone information.
|
||||
*/
|
||||
TimeZoneStorageType value() default TimeZoneStorageType.AUTO;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
* Describes the storage for the time zone information for time zone based types.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Incubating
|
||||
public enum TimeZoneStorageType {
|
||||
/**
|
||||
* Stores the time zone by using the "with time zone" type. Error if {@link Dialect#getTimeZoneSupport()} is not {@link org.hibernate.dialect.TimeZoneSupport#NATIVE}.
|
||||
*/
|
||||
NATIVE,
|
||||
/**
|
||||
* Does not store the time zone, and instead normalizes timestamps to UTC.
|
||||
*/
|
||||
NORMALIZE,
|
||||
/**
|
||||
* Stores the time zone in a separate column; works in conjunction with {@link TimeZoneColumn}.
|
||||
*/
|
||||
COLUMN,
|
||||
/**
|
||||
* Stores the time zone either with {@link #NATIVE} if {@link Dialect#getTimeZoneSupport()} is {@link org.hibernate.dialect.TimeZoneSupport#NATIVE}, otherwise uses the {@link #COLUMN} strategy.
|
||||
*/
|
||||
AUTO
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
/**
|
||||
* The type of storage to use for the time zone information.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
* @author Steve Ebersole
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Incubating
|
||||
public enum TimeZoneType {
|
||||
|
||||
/**
|
||||
* Stores the time zone id as String.
|
||||
*/
|
||||
ZONE_ID,
|
||||
/**
|
||||
* Stores the offset seconds of a timestamp as Integer.
|
||||
*/
|
||||
OFFSET;
|
||||
|
||||
}
|
|
@ -17,11 +17,6 @@ public class NoJdbcTypeDescriptor implements JdbcTypeDescriptor {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeRemapped() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -16,7 +16,9 @@ import jakarta.persistence.SharedCacheMode;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.hibernate.annotations.TimeZoneStorageType;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.boot.CacheRegionDefinition;
|
||||
import org.hibernate.boot.MetadataBuilder;
|
||||
|
@ -58,8 +60,10 @@ import org.hibernate.cache.spi.RegionFactory;
|
|||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.MetadataSourceType;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.log.DeprecationLogger;
|
||||
|
@ -533,6 +537,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
implements MetadataBuildingOptions, JpaOrmXmlPersistenceUnitDefaultAware {
|
||||
private final StandardServiceRegistry serviceRegistry;
|
||||
private final MappingDefaultsImpl mappingDefaults;
|
||||
private final TimeZoneStorageStrategy defaultTimezoneStorage;
|
||||
// todo (6.0) : remove bootstrapContext property along with the deprecated methods
|
||||
private BootstrapContext bootstrapContext;
|
||||
|
||||
|
@ -565,6 +570,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
|
||||
this.mappingDefaults = new MappingDefaultsImpl( serviceRegistry );
|
||||
|
||||
this.defaultTimezoneStorage = resolveTimeZoneStorageStrategy( serviceRegistry, configService );
|
||||
this.multiTenancyStrategy = MultiTenancyStrategy.determineMultiTenancyStrategy( configService.getSettings() );
|
||||
|
||||
this.xmlMappingEnabled = configService.getSetting(
|
||||
|
@ -744,6 +750,11 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
return mappingDefaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorage() {
|
||||
return defaultTimezoneStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||
return basicTypeRegistrations;
|
||||
|
@ -896,4 +907,54 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
this.bootstrapContext = bootstrapContext;
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeZoneStorageStrategy resolveTimeZoneStorageStrategy(
|
||||
StandardServiceRegistry serviceRegistry,
|
||||
ConfigurationService configService) {
|
||||
final TimeZoneStorageType configuredTimeZoneStorageType = configService.getSetting(
|
||||
AvailableSettings.TIMEZONE_DEFAULT_STORAGE,
|
||||
TimeZoneStorageType.class,
|
||||
null
|
||||
);
|
||||
final TimeZoneStorageStrategy resolvedTimezoneStorage;
|
||||
// For now, we default to NORMALIZE as that is the Hibernate 5.x behavior
|
||||
if ( configuredTimeZoneStorageType == null ) {
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.NORMALIZE;
|
||||
}
|
||||
else {
|
||||
final TimeZoneSupport timeZoneSupport = serviceRegistry.getService( JdbcServices.class )
|
||||
.getDialect()
|
||||
.getTimeZoneSupport();
|
||||
switch ( configuredTimeZoneStorageType ) {
|
||||
case NATIVE:
|
||||
if ( timeZoneSupport != TimeZoneSupport.NATIVE ) {
|
||||
throw new HibernateException( "The configured time zone storage type NATIVE is not supported with the configured dialect" );
|
||||
}
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.NATIVE;
|
||||
break;
|
||||
case COLUMN:
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.COLUMN;
|
||||
break;
|
||||
case NORMALIZE:
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.NORMALIZE;
|
||||
break;
|
||||
case AUTO:
|
||||
switch ( timeZoneSupport ) {
|
||||
case NATIVE:
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.NATIVE;
|
||||
break;
|
||||
case NORMALIZE:
|
||||
case NONE:
|
||||
resolvedTimezoneStorage = TimeZoneStorageStrategy.COLUMN;
|
||||
break;
|
||||
default:
|
||||
throw new HibernateException( "Unsupported time zone support: " + timeZoneSupport );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new HibernateException( "Unsupported time zone storage type: " + configuredTimeZoneStorageType );
|
||||
}
|
||||
}
|
||||
return resolvedTimezoneStorage;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.hibernate.Interceptor;
|
|||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.SchemaAutoTooling;
|
||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
|
@ -219,6 +220,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
private boolean conventionalJavaConstants;
|
||||
private final boolean omitJoinOfSuperclassTablesEnabled;
|
||||
private final int preferredSqlTypeCodeForBoolean;
|
||||
private final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
|
||||
|
||||
// Caching
|
||||
private boolean secondLevelCacheEnabled;
|
||||
|
@ -422,6 +424,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
CONVENTIONAL_JAVA_CONSTANTS, BOOLEAN, true );
|
||||
this.omitJoinOfSuperclassTablesEnabled = cfgService.getSetting( OMIT_JOIN_OF_SUPERCLASS_TABLES, BOOLEAN, true );
|
||||
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
|
||||
this.defaultTimeZoneStorageStrategy = context.getMetadataBuildingOptions().getDefaultTimeZoneStorage();
|
||||
|
||||
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
|
||||
if ( !NoCachingRegionFactory.class.isInstance( regionFactory ) ) {
|
||||
|
@ -1182,6 +1185,11 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return preferredSqlTypeCodeForBoolean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return defaultTimeZoneStorageStrategy;
|
||||
}
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// In-flight mutation access
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.boot.model.process.internal;
|
|||
import java.util.function.Function;
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
|
@ -57,6 +58,11 @@ public class VersionResolution<E> implements BasicValue.Resolution<E> {
|
|||
// if it is a temporal version, it needs to be a TIMESTAMP
|
||||
return TemporalType.TIMESTAMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return context.getBuildingOptions().getDefaultTimeZoneStorage();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -6,11 +6,15 @@
|
|||
*/
|
||||
package org.hibernate.boot.model.process.spi;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.internal.InFlightMetadataCollectorImpl;
|
||||
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
|
||||
|
@ -42,9 +46,10 @@ import org.hibernate.type.BasicType;
|
|||
import org.hibernate.type.BasicTypeRegistry;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.internal.NamedBasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
|
@ -420,5 +425,37 @@ public class MetadataBuildingProcess {
|
|||
// add explicit application registered types
|
||||
bootstrapContext.getTypeConfiguration()
|
||||
.addBasicTypeRegistrationContributions( options.getBasicTypeRegistrations() );
|
||||
|
||||
// For NORMALIZE, we replace the standard types that use TIMESTAMP_WITH_TIMEZONE to use TIMESTAMP
|
||||
if ( options.getDefaultTimeZoneStorage() == TimeZoneStorageStrategy.NORMALIZE ) {
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = bootstrapContext.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
final JavaTypeDescriptorRegistry javaTypeRegistry = bootstrapContext.getTypeConfiguration()
|
||||
.getJavaTypeDescriptorRegistry();
|
||||
final JdbcTypeDescriptor timestampDescriptor = jdbcTypeRegistry.getDescriptor( Types.TIMESTAMP );
|
||||
final BasicTypeRegistry basicTypeRegistry = bootstrapContext.getTypeConfiguration().getBasicTypeRegistry();
|
||||
final BasicType<?> offsetDateTimeType = new NamedBasicTypeImpl<>(
|
||||
javaTypeRegistry.getDescriptor( OffsetDateTime.class ),
|
||||
timestampDescriptor,
|
||||
"OffsetDateTime"
|
||||
);
|
||||
final BasicType<?> zonedDateTimeType = new NamedBasicTypeImpl<>(
|
||||
javaTypeRegistry.getDescriptor( ZonedDateTime.class ),
|
||||
timestampDescriptor,
|
||||
"ZonedDateTime"
|
||||
);
|
||||
basicTypeRegistry.register(
|
||||
offsetDateTimeType,
|
||||
"org.hibernate.type.OffsetDateTimeType",
|
||||
OffsetDateTime.class.getSimpleName(),
|
||||
OffsetDateTime.class.getName()
|
||||
);
|
||||
basicTypeRegistry.register(
|
||||
zonedDateTimeType,
|
||||
"org.hibernate.type.ZonedDateTimeType",
|
||||
ZonedDateTime.class.getSimpleName(),
|
||||
ZonedDateTime.class.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import jakarta.persistence.SharedCacheMode;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.boot.CacheRegionDefinition;
|
||||
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
|
||||
|
@ -55,6 +56,11 @@ public abstract class AbstractDelegatingMetadataBuildingOptions implements Metad
|
|||
return delegate.getMappingDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorage() {
|
||||
return delegate.getDefaultTimeZoneStorage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||
return delegate.getBasicTypeRegistrations();
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.EntityNameResolver;
|
|||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.SchemaAutoTooling;
|
||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
|
@ -468,4 +469,9 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
|||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return delegate.getPreferredSqlTypeCodeForBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return delegate.getDefaultTimeZoneStorageStrategy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import jakarta.persistence.SharedCacheMode;
|
||||
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.boot.CacheRegionDefinition;
|
||||
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
|
||||
|
@ -52,6 +53,8 @@ public interface MetadataBuildingOptions {
|
|||
*/
|
||||
MappingDefaults getMappingDefaults();
|
||||
|
||||
TimeZoneStorageStrategy getDefaultTimeZoneStorage();
|
||||
|
||||
default ManagedTypeRepresentationResolver getManagedTypeRepresentationResolver() {
|
||||
// for now always return the standard one
|
||||
return ManagedTypeRepresentationResolverStandard.INSTANCE;
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.EntityNameResolver;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.query.NullPrecedence;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
import org.hibernate.boot.SchemaAutoTooling;
|
||||
|
@ -348,4 +349,6 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
|||
boolean isOmitJoinOfSuperclassTablesEnabled();
|
||||
|
||||
int getPreferredSqlTypeCodeForBoolean();
|
||||
|
||||
TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy();
|
||||
}
|
||||
|
|
|
@ -2383,7 +2383,6 @@ public interface AvailableSettings {
|
|||
*/
|
||||
String OMIT_JOIN_OF_SUPERCLASS_TABLES = "hibernate.query.omit_join_of_superclass_tables";
|
||||
|
||||
|
||||
/**
|
||||
* Global setting identifying the preferred JDBC type code for storing
|
||||
* boolean values. The fallback is to ask the Dialect
|
||||
|
@ -2392,6 +2391,21 @@ public interface AvailableSettings {
|
|||
*/
|
||||
String PREFERRED_BOOLEAN_JDBC_TYPE_CODE = "hibernate.type.perferred_boolean_jdbc_type_code";
|
||||
|
||||
/**
|
||||
* Global setting for configuring the default storage for the time zone information for time zone based types.
|
||||
* </p>
|
||||
* Possible values are {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE},
|
||||
* {@link org.hibernate.annotations.TimeZoneStorageType#COLUMN},
|
||||
* {@link org.hibernate.annotations.TimeZoneStorageType#NATIVE}
|
||||
* and {@link org.hibernate.annotations.TimeZoneStorageType#AUTO}.
|
||||
* </p>
|
||||
* The default value is given by the {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE},
|
||||
* meaning that time zone information is not stored by default, but timestamps are normalized instead.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
String TIMEZONE_DEFAULT_STORAGE = "hibernate.timezone.default_storage";
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Java (javax) Persistence defined settings
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.function.Function;
|
|||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.annotations.AnyDiscriminator;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
import org.hibernate.annotations.AnyKeyJavaType;
|
||||
|
@ -190,6 +191,10 @@ public class BasicValueBinder<T> implements JdbcTypeDescriptorIndicators {
|
|||
public TypeConfiguration getTypeConfiguration() {
|
||||
return buildingContext.getBootstrapContext().getTypeConfiguration();
|
||||
}
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return buildingContext.getBuildingOptions().getDefaultTimeZoneStorage();
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -141,8 +141,8 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NORMALIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -54,8 +54,8 @@ public class DB2zDialect extends DB2Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return getZVersion() > 1000;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return getZVersion() > 1000 ? TimeZoneSupport.NATIVE : TimeZoneSupport.NONE;
|
||||
}
|
||||
|
||||
int getZVersion() {
|
||||
|
|
|
@ -3726,10 +3726,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether the Dialect supports timezone types like {@link Types#TIMESTAMP_WITH_TIMEZONE}.
|
||||
* How the Dialect supports time zone types like {@link Types#TIMESTAMP_WITH_TIMEZONE}.
|
||||
*/
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return false;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2
|
|||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.query.TemporalUnit.SECOND;
|
||||
|
@ -147,6 +148,11 @@ public class H2Dialect extends Dialect {
|
|||
);
|
||||
}
|
||||
|
||||
public boolean hasDstBug() {
|
||||
// H2 1.4.200 has a bug: https://github.com/h2database/h2database/issues/3184
|
||||
return getVersion() == 104200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return version;
|
||||
|
@ -265,8 +271,8 @@ public class H2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -567,8 +567,8 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return getVersion() >= 900;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return getVersion() >= 900 ? TimeZoneSupport.NATIVE : TimeZoneSupport.NONE;
|
||||
}
|
||||
|
||||
protected void registerBinaryTypeMappings() {
|
||||
|
|
|
@ -69,7 +69,6 @@ import org.hibernate.type.StandardBasicTypes;
|
|||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
|
@ -287,8 +286,8 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return true;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return TimeZoneSupport.NORMALIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -149,8 +149,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTimezoneTypes() {
|
||||
return getVersion() >= 10;
|
||||
public TimeZoneSupport getTimeZoneSupport() {
|
||||
return getVersion() >= 10 ? TimeZoneSupport.NATIVE : TimeZoneSupport.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
|||
import org.hibernate.type.descriptor.jdbc.NClobJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
@ -172,9 +171,10 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
|
||||
// The jTDS driver doesn't support the JDBC4 signatures using 'long length' for stream bindings
|
||||
jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcTypeDescriptor.CLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( Types.NCLOB, NClobJdbcTypeDescriptor.NCLOB_BINDING );
|
||||
// The jTDS driver doesn't support the JDBC4 setNString method
|
||||
jdbcTypeRegistry.addDescriptor( Types.NVARCHAR, NClobJdbcTypeDescriptor.NCLOB_BINDING );
|
||||
|
||||
// The jTDS driver doesn't support nationalized types
|
||||
jdbcTypeRegistry.addDescriptor( Types.NCLOB, ClobJdbcTypeDescriptor.CLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( Types.NVARCHAR, ClobJdbcTypeDescriptor.CLOB_BINDING );
|
||||
}
|
||||
else {
|
||||
// Some Sybase drivers cannot support getClob. See HHH-7889
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.dialect;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
/**
|
||||
* Describes the support for "with time zone" types.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
@Incubating
|
||||
public enum TimeZoneSupport {
|
||||
/**
|
||||
* The "with time zone" types retain the time zone information.
|
||||
*/
|
||||
NATIVE,
|
||||
/**
|
||||
* The "with time zone" types normalize to UTC.
|
||||
*/
|
||||
NORMALIZE,
|
||||
/**
|
||||
* No support for "with time zone" types.
|
||||
*/
|
||||
NONE;
|
||||
}
|
|
@ -17,6 +17,7 @@ import jakarta.persistence.PessimisticLockScope;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
|
||||
|
@ -66,7 +67,6 @@ import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
|||
import org.hibernate.jpa.internal.util.LockOptionsHelper;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_LOCK_SCOPE;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_LOCK_TIMEOUT;
|
||||
|
@ -147,6 +147,7 @@ public final class FastSessionServices {
|
|||
final boolean disallowOutOfTransactionUpdateOperations;
|
||||
final boolean useStreamForLobBinding;
|
||||
final int preferredSqlTypeCodeForBoolean;
|
||||
final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
|
||||
final boolean requiresMultiTenantConnectionProvider;
|
||||
final ConnectionProvider connectionProvider;
|
||||
final MultiTenantConnectionProvider multiTenantConnectionProvider;
|
||||
|
@ -216,6 +217,7 @@ public final class FastSessionServices {
|
|||
this.disallowOutOfTransactionUpdateOperations = !sessionFactoryOptions.isAllowOutOfTransactionUpdateOperations();
|
||||
this.useStreamForLobBinding = Environment.useStreamsForBinary() || dialect.useInputStreamToInsertBlob();
|
||||
this.preferredSqlTypeCodeForBoolean = sessionFactoryOptions.getPreferredSqlTypeCodeForBoolean();
|
||||
this.defaultTimeZoneStorageStrategy = sessionFactoryOptions.getDefaultTimeZoneStorageStrategy();
|
||||
this.requiresMultiTenantConnectionProvider = sf.getSettings().getMultiTenancyStrategy().requiresMultiTenantConnectionProvider();
|
||||
|
||||
//Some "hot" services:
|
||||
|
@ -361,4 +363,8 @@ public final class FastSessionServices {
|
|||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return preferredSqlTypeCodeForBoolean;
|
||||
}
|
||||
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return defaultTimeZoneStorageStrategy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.boot.model.TypeDefinition;
|
||||
import org.hibernate.boot.model.TypeDefinitionRegistry;
|
||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||
|
@ -68,7 +69,6 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
private static final CoreMessageLogger log = CoreLogging.messageLogger( BasicValue.class );
|
||||
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
private final int preferredJdbcTypeCodeForBoolean;
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// incoming "configuration" values
|
||||
|
@ -102,7 +102,6 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
super( buildingContext, table );
|
||||
|
||||
this.typeConfiguration = buildingContext.getBootstrapContext().getTypeConfiguration();
|
||||
this.preferredJdbcTypeCodeForBoolean = buildingContext.getPreferredSqlTypeCodeForBoolean();
|
||||
|
||||
buildingContext.getMetadataCollector().registerValueMappingResolver( this::resolve );
|
||||
}
|
||||
|
@ -600,7 +599,12 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return preferredJdbcTypeCodeForBoolean;
|
||||
return getBuildingContext().getPreferredSqlTypeCodeForBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return getBuildingContext().getBuildingOptions().getDefaultTimeZoneStorage();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ import jakarta.persistence.AttributeConverter;
|
|||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.annotations.common.reflection.XProperty;
|
||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||
|
@ -33,7 +34,6 @@ import org.hibernate.cfg.AvailableSettings;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.IdentityGenerator;
|
||||
|
@ -53,6 +53,7 @@ import org.hibernate.type.descriptor.converter.AttributeConverterJdbcTypeDescrip
|
|||
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
import org.hibernate.type.descriptor.jdbc.LobTypeMappings;
|
||||
import org.hibernate.type.descriptor.jdbc.NationalizedTypeMappings;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -668,7 +669,17 @@ public abstract class SimpleValue implements KeyValue {
|
|||
// VARCHAR/CHAR
|
||||
final JdbcTypeDescriptor recommendedJdbcType = jpaAttributeConverter.getRelationalJavaTypeDescriptor().getRecommendedJdbcType(
|
||||
// todo (6.0) : handle the other JdbcRecommendedSqlTypeMappingContext methods
|
||||
metadata::getTypeConfiguration
|
||||
new JdbcTypeDescriptorIndicators() {
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return metadata.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return buildingContext.getBuildingOptions().getDefaultTimeZoneStorage();
|
||||
}
|
||||
}
|
||||
);
|
||||
int jdbcTypeCode = recommendedJdbcType.getJdbcTypeCode();
|
||||
if ( isLob() ) {
|
||||
|
|
|
@ -388,7 +388,8 @@ public final class StandardBasicTypes {
|
|||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link OffsetDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}.
|
||||
* The standard Hibernate type for mapping {@link OffsetDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}
|
||||
* or {@link java.sql.Types#TIMESTAMP TIMESTAMP} depending on the {@link org.hibernate.cfg.AvailableSettings#TIMEZONE_DEFAULT_STORAGE} setting.
|
||||
*/
|
||||
public static final BasicTypeReference<OffsetDateTime> OFFSET_DATE_TIME = new BasicTypeReference<>(
|
||||
"OffsetDateTime",
|
||||
|
@ -396,18 +397,36 @@ public final class StandardBasicTypes {
|
|||
Types.TIMESTAMP_WITH_TIMEZONE
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link OffsetDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}.
|
||||
*/
|
||||
public static final BasicTypeReference<OffsetDateTime> OFFSET_DATE_TIME_WITH_TIMEZONE = new BasicTypeReference<>(
|
||||
"OffsetDateTimeWithTimezone",
|
||||
OffsetDateTime.class,
|
||||
Types.TIMESTAMP_WITH_TIMEZONE
|
||||
);
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link OffsetDateTime} to JDBC {@link java.sql.Types#TIMESTAMP TIMESTAMP}.
|
||||
*/
|
||||
public static final BasicTypeReference<OffsetDateTime> OFFSET_DATE_TIME_WITHOUT_TIMEZONE = new BasicTypeReference<>(
|
||||
"OffsetDateTimeWithoutTimezone",
|
||||
OffsetDateTime.class,
|
||||
Types.TIMESTAMP
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link OffsetTime} to JDBC {@link java.sql.Types#TIME TIME}.
|
||||
*/
|
||||
public static final BasicTypeReference<OffsetTime> OFFSET_TIME = new BasicTypeReference<>(
|
||||
"ZonedDateTime",
|
||||
"OffsetTime",
|
||||
OffsetTime.class,
|
||||
// todo (6.0): why not TIME_WITH_TIMEZONE ?
|
||||
Types.TIME
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link ZonedDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}.
|
||||
* The standard Hibernate type for mapping {@link ZonedDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}
|
||||
* or {@link java.sql.Types#TIMESTAMP TIMESTAMP} depending on the {@link org.hibernate.cfg.AvailableSettings#TIMEZONE_DEFAULT_STORAGE} setting.
|
||||
*/
|
||||
public static final BasicTypeReference<ZonedDateTime> ZONED_DATE_TIME = new BasicTypeReference<>(
|
||||
"ZonedDateTime",
|
||||
|
@ -415,6 +434,24 @@ public final class StandardBasicTypes {
|
|||
Types.TIMESTAMP_WITH_TIMEZONE
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link ZonedDateTime} to JDBC {@link java.sql.Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE}.
|
||||
*/
|
||||
public static final BasicTypeReference<ZonedDateTime> ZONED_DATE_TIME_WITH_TIMEZONE = new BasicTypeReference<>(
|
||||
"ZonedDateTimeWithTimezone",
|
||||
ZonedDateTime.class,
|
||||
Types.TIMESTAMP_WITH_TIMEZONE
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link ZonedDateTime} to JDBC {@link java.sql.Types#TIMESTAMP TIMESTAMP}.
|
||||
*/
|
||||
public static final BasicTypeReference<ZonedDateTime> ZONED_DATE_TIME_WITHOUT_TIMEZONE = new BasicTypeReference<>(
|
||||
"ZonedDateTimeWithoutTimezone",
|
||||
ZonedDateTime.class,
|
||||
Types.TIMESTAMP
|
||||
);
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link Instant} to JDBC
|
||||
* {@link java.sql.Types#TIMESTAMP TIMESTAMP}.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
@ -40,7 +41,7 @@ public class CalendarDateJavaTypeDescriptor extends AbstractTemporalJavaTypeDesc
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return DateJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.DATE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.GregorianCalendar;
|
||||
|
@ -49,7 +50,7 @@ public class CalendarJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimestampJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
@ -40,7 +41,7 @@ public class CalendarTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDesc
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIME );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
@ -57,7 +58,7 @@ public class DateJavaTypeDescriptor extends AbstractTemporalJavaTypeDescriptor<D
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimestampJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
|
@ -23,7 +24,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampJdbcTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -69,7 +69,7 @@ public class InstantJavaTypeDescriptor extends AbstractTemporalJavaTypeDescripto
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimestampJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,8 +94,7 @@ public class InstantJavaTypeDescriptor extends AbstractTemporalJavaTypeDescripto
|
|||
}
|
||||
|
||||
if ( Calendar.class.isAssignableFrom( type ) ) {
|
||||
final ZoneId zoneId = ZoneId.ofOffset( "UTC", ZoneOffset.UTC );
|
||||
return (X) GregorianCalendar.from( instant.atZone( zoneId ) );
|
||||
return (X) GregorianCalendar.from( instant.atZone( ZoneOffset.UTC ) );
|
||||
}
|
||||
|
||||
if ( Timestamp.class.isAssignableFrom( type ) ) {
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -73,7 +75,7 @@ public class JdbcDateJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return DateJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.DATE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,6 +168,11 @@ public class JdbcDateJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
if ( Long.class.isAssignableFrom( type ) ) {
|
||||
return (X) Long.valueOf( value.getTime() );
|
||||
}
|
||||
if ( LocalDate.class.isAssignableFrom( type ) ) {
|
||||
if ( value instanceof java.sql.Date ) {
|
||||
return (X) ( (java.sql.Date) value ).toLocalDate();
|
||||
}
|
||||
}
|
||||
throw unknownUnwrap( type );
|
||||
}
|
||||
|
||||
|
@ -190,6 +197,10 @@ public class JdbcDateJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
return new java.sql.Date( ( (Date) value ).getTime() );
|
||||
}
|
||||
|
||||
if ( value instanceof LocalDate ) {
|
||||
return java.sql.Date.valueOf( (LocalDate) value );
|
||||
}
|
||||
|
||||
throw unknownWrap( value.getClass() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Types;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -69,7 +71,7 @@ public class JdbcTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIME );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -164,6 +166,11 @@ public class JdbcTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
if ( Long.class.isAssignableFrom( type ) ) {
|
||||
return (X) Long.valueOf( value.getTime() );
|
||||
}
|
||||
if ( LocalTime.class.isAssignableFrom( type ) ) {
|
||||
if ( value instanceof Time ) {
|
||||
return (X) ( (Time) value ).toLocalTime();
|
||||
}
|
||||
}
|
||||
throw unknownUnwrap( type );
|
||||
}
|
||||
@Override
|
||||
|
@ -187,6 +194,10 @@ public class JdbcTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDescript
|
|||
return new Time( ( (Date) value ).getTime() );
|
||||
}
|
||||
|
||||
if ( value instanceof LocalTime ) {
|
||||
return Time.valueOf( (LocalTime) value );
|
||||
}
|
||||
|
||||
throw unknownWrap( value.getClass() );
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
@ -76,7 +78,7 @@ public class JdbcTimestampJavaTypeDescriptor extends AbstractTemporalJavaTypeDes
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimestampJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -48,7 +49,7 @@ public class LocalDateJavaTypeDescriptor extends AbstractTemporalJavaTypeDescrip
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return DateJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.DATE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
@ -49,7 +50,7 @@ public class LocalDateTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDes
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimestampJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.type.descriptor.java;
|
|||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -52,7 +53,7 @@ public class LocalTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDescrip
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIME );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,26 +7,25 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.jdbc.DateJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
import org.hibernate.type.descriptor.jdbc.TimeJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -54,17 +53,20 @@ public class OffsetDateTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDe
|
|||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators stdIndicators) {
|
||||
final TemporalType temporalPrecision = stdIndicators.getTemporalPrecision();
|
||||
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = stdIndicators.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
if ( temporalPrecision == null || temporalPrecision == TemporalType.TIMESTAMP ) {
|
||||
return TimestampWithTimeZoneJdbcTypeDescriptor.INSTANCE;
|
||||
return stdIndicators.getDefaultTimeZoneStorageStrategy() == TimeZoneStorageStrategy.NORMALIZE
|
||||
? jdbcTypeRegistry.getDescriptor( Types.TIMESTAMP )
|
||||
: jdbcTypeRegistry.getDescriptor( Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
}
|
||||
|
||||
switch ( temporalPrecision ) {
|
||||
case TIME: {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return jdbcTypeRegistry.getDescriptor( Types.TIME );
|
||||
}
|
||||
case DATE: {
|
||||
return DateJdbcTypeDescriptor.INSTANCE;
|
||||
return jdbcTypeRegistry.getDescriptor( Types.DATE );
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException( "Unexpected jakarta.persistence.TemporalType : " + temporalPrecision );
|
||||
|
|
|
@ -8,8 +8,11 @@ package org.hibernate.type.descriptor.java;
|
|||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
@ -51,7 +54,7 @@ public class OffsetTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDescri
|
|||
|
||||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators context) {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return context.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( Types.TIME );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,27 +7,26 @@
|
|||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.ZonedDateTimeComparator;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.jdbc.DateJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
import org.hibernate.type.descriptor.jdbc.TimeJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -54,16 +53,20 @@ public class ZonedDateTimeJavaTypeDescriptor extends AbstractTemporalJavaTypeDes
|
|||
@Override
|
||||
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators stdIndicators) {
|
||||
final TemporalType temporalPrecision = stdIndicators.getTemporalPrecision();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = stdIndicators.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
if ( temporalPrecision == null || temporalPrecision == TemporalType.TIMESTAMP ) {
|
||||
return TimestampWithTimeZoneJdbcTypeDescriptor.INSTANCE;
|
||||
return stdIndicators.getDefaultTimeZoneStorageStrategy() == TimeZoneStorageStrategy.NORMALIZE
|
||||
? jdbcTypeRegistry.getDescriptor( Types.TIMESTAMP )
|
||||
: jdbcTypeRegistry.getDescriptor( Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
}
|
||||
|
||||
switch ( temporalPrecision ) {
|
||||
case TIME: {
|
||||
return TimeJdbcTypeDescriptor.INSTANCE;
|
||||
return jdbcTypeRegistry.getDescriptor( Types.TIME );
|
||||
}
|
||||
case DATE: {
|
||||
return DateJdbcTypeDescriptor.INSTANCE;
|
||||
return jdbcTypeRegistry.getDescriptor( Types.DATE );
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException( "Unexpected jakarta.persistence.TemporalType : " + temporalPrecision );
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.sql.Types;
|
|||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.TimeZoneStorageStrategy;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -76,6 +77,10 @@ public interface JdbcTypeDescriptorIndicators {
|
|||
return NO_COLUMN_LENGTH;
|
||||
}
|
||||
|
||||
default TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return getTypeConfiguration().getSessionFactory().getFastSessionServices().getDefaultTimeZoneStorageStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the TypeConfiguration for access to various type-system registries.
|
||||
*/
|
||||
|
|
|
@ -14,7 +14,7 @@ import java.util.Currency;
|
|||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class MonetaryAmount implements Serializable {
|
||||
public class MonetaryAmount {
|
||||
|
||||
private BigDecimal amount;
|
||||
private Currency currency;
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.annotations.Nationalized;
|
|||
import org.hibernate.annotations.JdbcType;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.JdbcTypeRegistration;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.NationalizationSupport;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
|
@ -30,6 +31,7 @@ import org.hibernate.type.descriptor.ValueExtractor;
|
|||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||
|
@ -50,20 +52,42 @@ public class JdbcTypeTests {
|
|||
|
||||
@Test
|
||||
public void verifyResolutions(DomainModelScope scope) {
|
||||
final Dialect dialect = scope.getDomainModel()
|
||||
.getDatabase()
|
||||
.getDialect();
|
||||
final MetadataImplementor domainModel = scope.getDomainModel();
|
||||
final Dialect dialect = domainModel.getDatabase().getDialect();
|
||||
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
final PersistentClass entityBinding = domainModel.getEntityBinding( SimpleEntity.class.getName() );
|
||||
|
||||
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding( SimpleEntity.class.getName() );
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "materializedClob" ),
|
||||
jdbcTypeRegistry.getDescriptor( Types.CLOB ).getJdbcTypeCode()
|
||||
);
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "materializedNClob" ),
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() )
|
||||
.getJdbcTypeCode()
|
||||
);
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "jpaMaterializedClob" ),
|
||||
jdbcTypeRegistry.getDescriptor( Types.CLOB ).getJdbcTypeCode()
|
||||
);
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "jpaMaterializedNClob" ),
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() )
|
||||
.getJdbcTypeCode()
|
||||
);
|
||||
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "materializedClob" ), Types.CLOB );
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "materializedNClob" ), nationalizationSupport.getClobVariantCode() );
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "jpaMaterializedClob" ), Types.CLOB );
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "jpaMaterializedNClob" ), nationalizationSupport.getClobVariantCode() );
|
||||
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "nationalizedString" ), nationalizationSupport.getVarcharVariantCode() );
|
||||
verifyJdbcTypeCode( entityBinding.getProperty( "nationalizedClob" ), nationalizationSupport.getClobVariantCode() );
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "nationalizedString" ),
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() )
|
||||
.getJdbcTypeCode()
|
||||
);
|
||||
verifyJdbcTypeCode(
|
||||
entityBinding.getProperty( "nationalizedClob" ),
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode() )
|
||||
.getJdbcTypeCode()
|
||||
);
|
||||
|
||||
verifyResolution( entityBinding.getProperty( "customType" ), CustomJdbcTypeDescriptor.class );
|
||||
verifyResolution( entityBinding.getProperty( "customTypeRegistration" ), RegisteredCustomJdbcTypeDescriptor.class );
|
||||
|
|
|
@ -12,11 +12,13 @@ import java.util.function.Consumer;
|
|||
|
||||
import org.hibernate.annotations.ListIndexJdbcType;
|
||||
import org.hibernate.annotations.ListIndexJdbcTypeCode;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||
|
@ -42,11 +44,17 @@ public class ListIndexJdbcTypeTests {
|
|||
|
||||
@Test
|
||||
public void verifyResolutions(DomainModelScope scope) {
|
||||
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding( TheEntity.class.getName() );
|
||||
final MetadataImplementor domainModel = scope.getDomainModel();
|
||||
final PersistentClass entityBinding = domainModel.getEntityBinding( TheEntity.class.getName() );
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
verifyJdbcTypeCodes( entityBinding.getProperty( "listOfStrings" ), Types.TINYINT );
|
||||
|
||||
verifyJdbcTypeCodes( entityBinding.getProperty( "anotherListOfStrings" ), Types.TINYINT );
|
||||
verifyJdbcTypeCodes(
|
||||
entityBinding.getProperty( "anotherListOfStrings" ),
|
||||
jdbcTypeRegistry.getDescriptor( Types.TINYINT ).getJdbcTypeCode()
|
||||
);
|
||||
}
|
||||
private void verifyJdbcTypeCodes(Property property, int expectedCode) {
|
||||
verifyJdbcTypeResolution(
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.function.Consumer;
|
|||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.MapKeyJdbcType;
|
||||
import org.hibernate.annotations.MapKeyJdbcTypeCode;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.NationalizationSupport;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
|
@ -21,6 +22,7 @@ import org.hibernate.mapping.PersistentClass;
|
|||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TinyIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||
|
@ -45,27 +47,30 @@ public class MapKeyJdbcTypeTests {
|
|||
|
||||
@Test
|
||||
public void verifyResolutions(DomainModelScope scope) {
|
||||
final Dialect dialect = scope.getDomainModel().getDatabase().getDialect();
|
||||
final MetadataImplementor domainModel = scope.getDomainModel();
|
||||
final Dialect dialect = domainModel.getDatabase().getDialect();
|
||||
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = domainModel.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding( MyEntity.class.getName() );
|
||||
final PersistentClass entityBinding = domainModel.getEntityBinding( MyEntity.class.getName() );
|
||||
|
||||
verifyJdbcTypeCodes(
|
||||
entityBinding.getProperty( "baseMap" ),
|
||||
Types.INTEGER,
|
||||
Types.VARCHAR
|
||||
jdbcTypeRegistry.getDescriptor( Types.INTEGER ).getJdbcTypeCode(),
|
||||
jdbcTypeRegistry.getDescriptor( Types.VARCHAR ).getJdbcTypeCode()
|
||||
);
|
||||
|
||||
verifyJdbcTypeCodes(
|
||||
entityBinding.getProperty( "sqlTypeCodeMap" ),
|
||||
Types.TINYINT,
|
||||
nationalizationSupport.getVarcharVariantCode()
|
||||
jdbcTypeRegistry.getDescriptor( Types.TINYINT ).getJdbcTypeCode(),
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() ).getJdbcTypeCode()
|
||||
);
|
||||
|
||||
verifyJdbcTypeCodes(
|
||||
entityBinding.getProperty( "sqlTypeMap" ),
|
||||
Types.TINYINT,
|
||||
nationalizationSupport.getVarcharVariantCode()
|
||||
jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode() ).getJdbcTypeCode()
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.hibernate.type.descriptor.jdbc.NCharJdbcTypeDescriptor;
|
|||
import org.hibernate.type.descriptor.jdbc.NClobJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.NVarcharJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -88,6 +90,9 @@ public class SimpleNationalizedTest {
|
|||
ms.addAnnotatedClass( NationalizedEntity.class );
|
||||
|
||||
final Metadata metadata = ms.buildMetadata();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = metadata.getDatabase()
|
||||
.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
PersistentClass pc = metadata.getEntityBinding( NationalizedEntity.class.getName() );
|
||||
assertNotNull( pc );
|
||||
|
||||
|
@ -96,77 +101,58 @@ public class SimpleNationalizedTest {
|
|||
final Dialect dialect = metadata.getDatabase().getDialect();
|
||||
assertSame( StringJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
assertSame( VarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.VARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( NVarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NVARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
|
||||
prop = pc.getProperty( "materializedNclobAtt" );
|
||||
type = (BasicType<?>) prop.getType();
|
||||
assertSame( StringJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
if ( dialect instanceof SybaseDialect ) {
|
||||
assertSame( ClobJdbcTypeDescriptor.CLOB_BINDING, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.CLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( ClobJdbcTypeDescriptor.DEFAULT, type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assertSame( NClobJdbcTypeDescriptor.DEFAULT, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NCLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
prop = pc.getProperty( "nclobAtt" );
|
||||
type = (BasicType<?>) prop.getType();
|
||||
assertSame( NClobJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
if ( dialect instanceof SybaseDialect ) {
|
||||
assertSame( ClobJdbcTypeDescriptor.CLOB_BINDING, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.CLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( ClobJdbcTypeDescriptor.DEFAULT, type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assertSame( NClobJdbcTypeDescriptor.DEFAULT, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NCLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
|
||||
prop = pc.getProperty( "nlongvarcharcharAtt" );
|
||||
{
|
||||
final BasicValue.Resolution<?> resolution = ( (BasicValue) prop.getValue() ).resolve();
|
||||
|
||||
final int jdbcTypeExpected;
|
||||
type = (BasicType<?>) prop.getType();
|
||||
assertSame( StringJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
jdbcTypeExpected = Types.CLOB;
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.CLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
jdbcTypeExpected = Types.NCLOB;
|
||||
}
|
||||
Assertions.assertThat( resolution.getJdbcTypeDescriptor().getJdbcTypeCode() ).isEqualTo( jdbcTypeExpected );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NCLOB ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
|
||||
prop = pc.getProperty( "ncharArrAtt" );
|
||||
type = (BasicType<?>) prop.getType();
|
||||
assertSame( CharacterArrayJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
assertSame( VarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.VARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( NVarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NVARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
prop = pc.getProperty( "ncharacterAtt" );
|
||||
type = (BasicType<?>) prop.getType();
|
||||
assertSame( CharacterJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
assertSame( CharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.CHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( NCharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
assertSame( jdbcTypeRegistry.getDescriptor( Types.NCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.nationalized;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
|
@ -27,10 +29,12 @@ import org.hibernate.type.descriptor.jdbc.CharJdbcTypeDescriptor;
|
|||
import org.hibernate.type.descriptor.jdbc.NCharJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.NVarcharJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
|
@ -53,18 +57,19 @@ public class UseNationalizedCharDataSettingTest extends BaseUnitTestCase {
|
|||
ms.addAnnotatedClass( NationalizedBySettingEntity.class );
|
||||
|
||||
final Metadata metadata = ms.buildMetadata();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = metadata.getDatabase()
|
||||
.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
final PersistentClass pc = metadata.getEntityBinding( NationalizedBySettingEntity.class.getName() );
|
||||
final Property nameAttribute = pc.getProperty( "name" );
|
||||
final BasicType<?> type = (BasicType<?>) nameAttribute.getType();
|
||||
final Dialect dialect = metadata.getDatabase().getDialect();
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
// See issue HHH-10693
|
||||
assertSame( StringJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
assertSame( VarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
Assertions.assertSame( jdbcTypeRegistry.getDescriptor( Types.VARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( StringJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
assertSame( NVarcharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
Assertions.assertSame( jdbcTypeRegistry.getDescriptor( Types.NVARCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,17 +90,19 @@ public class UseNationalizedCharDataSettingTest extends BaseUnitTestCase {
|
|||
ms.addAnnotatedClass( NationalizedBySettingEntity.class );
|
||||
|
||||
final Metadata metadata = ms.buildMetadata();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = metadata.getDatabase()
|
||||
.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
final PersistentClass pc = metadata.getEntityBinding( NationalizedBySettingEntity.class.getName() );
|
||||
final Property nameAttribute = pc.getProperty( "flag" );
|
||||
final BasicType<?> type = (BasicType<?>) nameAttribute.getType();
|
||||
final Dialect dialect = metadata.getDatabase().getDialect();
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
assertSame( CharacterJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
assertSame( CharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
if ( dialect.getNationalizationSupport() != NationalizationSupport.EXPLICIT ) {
|
||||
Assertions.assertSame( jdbcTypeRegistry.getDescriptor( Types.CHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
assertSame( CharacterJavaTypeDescriptor.INSTANCE, type.getJavaTypeDescriptor() );
|
||||
assertSame( NCharJdbcTypeDescriptor.INSTANCE, type.getJdbcTypeDescriptor() );
|
||||
Assertions.assertSame( jdbcTypeRegistry.getDescriptor( Types.NCHAR ), type.getJdbcTypeDescriptor() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -20,6 +20,7 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
|
@ -27,7 +28,6 @@ import org.hibernate.cfg.Configuration;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
@ -47,7 +47,7 @@ import static org.junit.Assert.assertEquals;
|
|||
* @param <E> The entity type used in tests.
|
||||
*/
|
||||
@RunWith(CustomParameterized.class)
|
||||
abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase {
|
||||
public abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase {
|
||||
|
||||
private static Dialect determineDialect() {
|
||||
try {
|
||||
|
@ -287,6 +287,13 @@ abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase
|
|||
return thisAsS();
|
||||
}
|
||||
|
||||
public S skippedForDialects(Predicate<Dialect> skipPredicate, Consumer<S> skippedIfDialectMatchesClasses) {
|
||||
if ( !skipPredicate.test( dialect ) ) {
|
||||
skippedIfDialectMatchesClasses.accept( thisAsS() );
|
||||
}
|
||||
return thisAsS();
|
||||
}
|
||||
|
||||
public S withForcedJdbcTimezone(String zoneIdString, Consumer<S> contributor) {
|
||||
ZoneId zoneId = ZoneId.of( zoneIdString );
|
||||
this.forcedJdbcTimeZone = zoneId;
|
||||
|
@ -301,7 +308,7 @@ abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase
|
|||
|
||||
@SafeVarargs
|
||||
public final S alsoTestRemappingsWithH2(Class<? extends AbstractRemappingH2Dialect> ... dialectClasses) {
|
||||
if ( dialect instanceof H2Dialect ) {
|
||||
if ( dialect instanceof H2Dialect && !( (H2Dialect) dialect ).hasDstBug() ) {
|
||||
// Only test remappings with H2
|
||||
Collections.addAll( remappingDialectClasses, dialectClasses );
|
||||
}
|
||||
|
@ -395,11 +402,12 @@ abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase
|
|||
|
||||
protected static class AbstractRemappingH2Dialect extends H2Dialect {
|
||||
private final int overriddenSqlTypeCode;
|
||||
private final JdbcTypeDescriptor overriddenJdbcTypeDescriptor;
|
||||
private final int overridingSqlTypeCode;
|
||||
|
||||
public AbstractRemappingH2Dialect(int overriddenSqlTypeCode, JdbcTypeDescriptor overriddenJdbcTypeDescriptor) {
|
||||
public AbstractRemappingH2Dialect(int overriddenSqlTypeCode, int overridingSqlTypeCode) {
|
||||
super( getDialect().getVersion() );
|
||||
this.overriddenSqlTypeCode = overriddenSqlTypeCode;
|
||||
this.overriddenJdbcTypeDescriptor = overriddenJdbcTypeDescriptor;
|
||||
this.overridingSqlTypeCode = overridingSqlTypeCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -408,7 +416,9 @@ abstract class AbstractJavaTimeTypeTest<T, E> extends BaseCoreFunctionalTestCase
|
|||
|
||||
typeContributions.getTypeConfiguration().getJdbcTypeDescriptorRegistry().addDescriptor(
|
||||
overriddenSqlTypeCode,
|
||||
overriddenJdbcTypeDescriptor
|
||||
typeContributions.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor(
|
||||
overridingSqlTypeCode
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.query.Query;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -22,8 +22,10 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
|
||||
import org.junit.runners.Parameterized;
|
||||
|
@ -61,21 +63,26 @@ public class InstantTest extends AbstractJavaTimeTypeTest<Instant, InstantTest.E
|
|||
.add( 1900, 1, 2, 0, 9, 21, 0, ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 0, 0, 0, ZONE_AMSTERDAM )
|
||||
.add( 1900, 1, 2, 0, 19, 32, 0, ZONE_AMSTERDAM )
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, ZONE_OSLO )
|
||||
.add( 1899, 12, 31, 23, 59, 59, 999_999_999, ZONE_PARIS )
|
||||
.add( 1899, 12, 31, 23, 59, 59, 999_999_999, ZONE_AMSTERDAM )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb/Sybase cannot store dates in 1600 in a timestamp.
|
||||
Arrays.asList( MySQLDialect.class, MariaDBDialect.class, SybaseDialect.class ),
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect
|
||||
|| dialect instanceof SybaseDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 1600, 1, 1, 0, 0, 0, 0, ZONE_AMSTERDAM )
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, ZONE_OSLO )
|
||||
)
|
||||
// HHH-13379: DST end (where Timestamp becomes ambiguous, see JDK-4312621)
|
||||
// => This used to work correctly in 5.4.1.Final and earlier
|
||||
.add( 2018, 10, 28, 1, 0, 0, 0, ZONE_PARIS )
|
||||
.skippedForDialects(
|
||||
dialect -> dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b.add( 2018, 10, 28, 1, 0, 0, 0, ZONE_PARIS )
|
||||
.add( 2018, 3, 31, 14, 0, 0, 0, ZONE_AUCKLAND )
|
||||
)
|
||||
// => This has never worked correctly, unless the JDBC timezone was set to UTC
|
||||
.withForcedJdbcTimezone( "UTC", b -> b
|
||||
.add( 2018, 10, 28, 0, 0, 0, 0, ZONE_PARIS )
|
||||
|
@ -83,8 +90,12 @@ public class InstantTest extends AbstractJavaTimeTypeTest<Instant, InstantTest.E
|
|||
)
|
||||
// => Also test DST start, just in case
|
||||
.add( 2018, 3, 25, 1, 0, 0, 0, ZONE_PARIS )
|
||||
.add( 2018, 3, 25, 2, 0, 0, 0, ZONE_PARIS )
|
||||
.skippedForDialects(
|
||||
// No idea what Sybase is doing here exactly
|
||||
dialect -> dialect instanceof SybaseASEDialect,
|
||||
b -> b.add( 2018, 3, 25, 2, 0, 0, 0, ZONE_PARIS )
|
||||
.add( 2018, 9, 30, 2, 0, 0, 0, ZONE_AUCKLAND )
|
||||
)
|
||||
.add( 2018, 9, 30, 3, 0, 0, 0, ZONE_AUCKLAND )
|
||||
// => Also test dates around 1905-01-01, because the code behaves differently before and after 1905
|
||||
.add( 1904, 12, 31, 22, 59, 59, 999_999_999, ZONE_PARIS )
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertFalse;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
|
@ -22,10 +22,11 @@ import jakarta.persistence.Entity;
|
|||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQL5Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampJdbcTypeDescriptor;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
@ -37,11 +38,13 @@ import org.junit.runners.Parameterized;
|
|||
@TestForIssue(jiraKey = "HHH-10371")
|
||||
@SkipForDialect(value = AbstractHANADialect.class,
|
||||
comment = "HANA systematically returns the wrong date when the JVM default timezone is not UTC")
|
||||
@SkipForDialect(value = MySQL5Dialect.class,
|
||||
@SkipForDialect(value = MySQLDialect.class,
|
||||
comment = "HHH-13582: MySQL ConnectorJ 8.x returns the wrong date"
|
||||
+ " when the JVM default timezone is different from the server timezone:"
|
||||
+ " https://bugs.mysql.com/bug.php?id=91112"
|
||||
)
|
||||
@SkipForDialect(value = H2Dialect.class, comment = "H2 1.4.200 DST bug. See org.hibernate.dialect.H2Dialect.hasDstBug")
|
||||
@SkipForDialect(value = HSQLDialect.class, comment = "HSQL has problems with DST edges")
|
||||
public class LocalDateTest extends AbstractJavaTimeTypeTest<LocalDate, LocalDateTest.EntityWithLocalDate> {
|
||||
|
||||
private static class ParametersBuilder extends AbstractParametersBuilder<ParametersBuilder> {
|
||||
|
@ -70,7 +73,11 @@ public class LocalDateTest extends AbstractJavaTimeTypeTest<LocalDate, LocalDate
|
|||
.add( 1892, 1, 1, ZONE_OSLO )
|
||||
.add( 1900, 1, 1, ZONE_PARIS )
|
||||
.add( 1900, 1, 1, ZONE_AMSTERDAM )
|
||||
.add( 1600, 1, 1, ZONE_AMSTERDAM )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// No idea what Sybase is doing here exactly
|
||||
dialect -> dialect instanceof SybaseASEDialect,
|
||||
b -> b.add( 1600, 1, 1, ZONE_AMSTERDAM )
|
||||
)
|
||||
// HHH-13379: DST end (where Timestamp becomes ambiguous, see JDK-4312621)
|
||||
// It doesn't seem that any date at midnight can be affected by HHH-13379, but we add some tests just in case
|
||||
|
@ -167,7 +174,7 @@ public class LocalDateTest extends AbstractJavaTimeTypeTest<LocalDate, LocalDate
|
|||
|
||||
public static class DateAsTimestampRemappingH2Dialect extends AbstractRemappingH2Dialect {
|
||||
public DateAsTimestampRemappingH2Dialect() {
|
||||
super( Types.DATE, TimestampJdbcTypeDescriptor.INSTANCE );
|
||||
super( Types.DATE, Types.TIMESTAMP );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -19,6 +19,7 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
|
@ -56,25 +57,40 @@ public class LocalDateTimeTest extends AbstractJavaTimeTypeTest<LocalDateTime, L
|
|||
.add( 1900, 1, 1, 0, 0, 0, 0, ZONE_OSLO )
|
||||
.add( 1900, 1, 2, 0, 9, 21, 0, ZONE_PARIS )
|
||||
.add( 1900, 1, 2, 0, 19, 32, 0, ZONE_AMSTERDAM )
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, ZONE_OSLO )
|
||||
.add( 1900, 1, 1, 0, 9, 20, 0, ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, ZONE_AMSTERDAM )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb cannot store values equal to epoch exactly, or less, in a timestamp.
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, ZONE_OSLO )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb/Sybase cannot store dates in 1600 in a timestamp.
|
||||
Arrays.asList( MySQLDialect.class, MariaDBDialect.class, SybaseDialect.class ),
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect || dialect instanceof SybaseDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 1600, 1, 1, 0, 0, 0, 0, ZONE_AMSTERDAM )
|
||||
)
|
||||
// HHH-13379: DST end (where Timestamp becomes ambiguous, see JDK-4312621)
|
||||
// It doesn't seem that any LocalDateTime can be affected by HHH-13379, but we add some tests just in case
|
||||
.add( 2018, 10, 28, 1, 0, 0, 0, ZONE_PARIS )
|
||||
.skippedForDialects(
|
||||
dialect -> dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 2018, 10, 28, 2, 0, 0, 0, ZONE_PARIS )
|
||||
)
|
||||
.add( 2018, 10, 28, 3, 0, 0, 0, ZONE_PARIS )
|
||||
.add( 2018, 10, 28, 4, 0, 0, 0, ZONE_PARIS )
|
||||
.add( 2018, 4, 1, 1, 0, 0, 0, ZONE_AUCKLAND )
|
||||
.skippedForDialects(
|
||||
dialect -> dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 2018, 4, 1, 2, 0, 0, 0, ZONE_AUCKLAND )
|
||||
)
|
||||
.add( 2018, 4, 1, 3, 0, 0, 0, ZONE_AUCKLAND )
|
||||
.add( 2018, 4, 1, 4, 0, 0, 0, ZONE_AUCKLAND )
|
||||
// => Also test DST start
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -23,10 +23,10 @@ import jakarta.persistence.Entity;
|
|||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQL5Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampJdbcTypeDescriptor;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
|
@ -35,6 +35,7 @@ import org.junit.runners.Parameterized;
|
|||
/**
|
||||
* Tests for storage of LocalTime properties.
|
||||
*/
|
||||
@SkipForDialect(value = H2Dialect.class, comment = "H2 1.4.200 DST bug. See org.hibernate.dialect.H2Dialect.hasDstBug")
|
||||
public class LocalTimeTest extends AbstractJavaTimeTypeTest<LocalTime, LocalTimeTest.EntityWithLocalTime> {
|
||||
|
||||
private static class ParametersBuilder extends AbstractParametersBuilder<ParametersBuilder> {
|
||||
|
@ -200,12 +201,13 @@ public class LocalTimeTest extends AbstractJavaTimeTypeTest<LocalTime, LocalTime
|
|||
@Override
|
||||
@Test
|
||||
@SkipForDialect(value = AbstractHANADialect.class, comment = "HANA seems to return a java.sql.Timestamp instead of a java.sql.Time")
|
||||
@SkipForDialect(value = MySQL5Dialect.class,
|
||||
@SkipForDialect(value = MySQLDialect.class,
|
||||
comment = "HHH-13580 MySQL seems to store the whole timestamp, not just the time,"
|
||||
+ " which for some timezones results in a date other than 1970-01-01 being returned"
|
||||
+ " (typically 1969-12-31), even though the time is always right."
|
||||
+ " Since java.sql.Time holds the whole timestamp, not just the time,"
|
||||
+ " its equals() method ends up returning false in this test.")
|
||||
@SkipForDialect(value = HSQLDialect.class, comment = "Timezone issue?")
|
||||
public void writeThenNativeRead() {
|
||||
super.writeThenNativeRead();
|
||||
}
|
||||
|
@ -231,7 +233,7 @@ public class LocalTimeTest extends AbstractJavaTimeTypeTest<LocalTime, LocalTime
|
|||
|
||||
public static class TimeAsTimestampRemappingH2Dialect extends AbstractRemappingH2Dialect {
|
||||
public TimeAsTimestampRemappingH2Dialect() {
|
||||
super( Types.TIME, TimestampJdbcTypeDescriptor.INSTANCE );
|
||||
super( Types.TIME, Types.TIMESTAMP );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -22,11 +22,11 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.type.OffsetDateTimeType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
@ -88,22 +88,32 @@ public class OffsetDateTimeTest extends AbstractJavaTimeTypeTest<OffsetDateTime,
|
|||
.add( 1900, 1, 1, 0, 9, 21, 0, "+00:09:21", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 32, 0, "+00:19:32", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 32, 0, "+00:19:32", ZONE_AMSTERDAM )
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "+00:00", ZONE_OSLO )
|
||||
.add( 1900, 1, 1, 0, 9, 20, 0, "+00:09:21", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, "+00:19:32", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, "+00:19:32", ZONE_AMSTERDAM )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb cannot store values equal to epoch exactly, or less, in a timestamp.
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "+00:00", ZONE_OSLO )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb/Sybase cannot store dates in 1600 in a timestamp.
|
||||
Arrays.asList( MySQLDialect.class, MariaDBDialect.class, SybaseDialect.class ),
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect || dialect instanceof SybaseDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 1600, 1, 1, 0, 0, 0, 0, "+00:19:32", ZONE_AMSTERDAM )
|
||||
)
|
||||
// HHH-13379: DST end (where Timestamp becomes ambiguous, see JDK-4312621)
|
||||
// => This used to work correctly in 5.4.1.Final and earlier
|
||||
.add( 2018, 10, 28, 2, 0, 0, 0, "+01:00", ZONE_PARIS )
|
||||
.skippedForDialects(
|
||||
dialect -> dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b.add( 2018, 10, 28, 2, 0, 0, 0, "+01:00", ZONE_PARIS )
|
||||
.add( 2018, 4, 1, 2, 0, 0, 0, "+12:00", ZONE_AUCKLAND )
|
||||
)
|
||||
// => This has never worked correctly, unless the JDBC timezone was set to UTC
|
||||
.withForcedJdbcTimezone( "UTC", b -> b
|
||||
.add( 2018, 10, 28, 2, 0, 0, 0, "+02:00", ZONE_PARIS )
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -25,11 +25,9 @@ import jakarta.persistence.Entity;
|
|||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQL5Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.type.descriptor.jdbc.BigIntJdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.TimestampJdbcTypeDescriptor;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
|
@ -229,12 +227,13 @@ public class OffsetTimeTest extends AbstractJavaTimeTypeTest<OffsetTime, OffsetT
|
|||
@Override
|
||||
@Test
|
||||
@SkipForDialect(value = AbstractHANADialect.class, comment = "HANA seems to return a java.sql.Timestamp instead of a java.sql.Time")
|
||||
@SkipForDialect(value = MySQL5Dialect.class,
|
||||
@SkipForDialect(value = MySQLDialect.class,
|
||||
comment = "HHH-13580 MySQL seems to store the whole timestamp, not just the time,"
|
||||
+ " which for some timezones results in a date other than 1970-01-01 being returned"
|
||||
+ " (typically 1969-12-31), even though the time is always right."
|
||||
+ " Since java.sql.Time holds the whole timestamp, not just the time,"
|
||||
+ " its equals() method ends up returning false in this test.")
|
||||
@SkipForDialect(value = HSQLDialect.class, comment = "Timezone issue?")
|
||||
public void writeThenNativeRead() {
|
||||
super.writeThenNativeRead();
|
||||
}
|
||||
|
@ -260,13 +259,13 @@ public class OffsetTimeTest extends AbstractJavaTimeTypeTest<OffsetTime, OffsetT
|
|||
|
||||
public static class TimeAsTimestampRemappingH2Dialect extends AbstractRemappingH2Dialect {
|
||||
public TimeAsTimestampRemappingH2Dialect() {
|
||||
super( Types.TIME, TimestampJdbcTypeDescriptor.INSTANCE );
|
||||
super( Types.TIME, Types.TIMESTAMP );
|
||||
}
|
||||
}
|
||||
|
||||
public static class TimeAsBigIntRemappingH2Dialect extends AbstractRemappingH2Dialect {
|
||||
public TimeAsBigIntRemappingH2Dialect() {
|
||||
super( Types.TIME, BigIntJdbcTypeDescriptor.INSTANCE );
|
||||
super( Types.TIME, Types.BIGINT );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
|
@ -17,35 +17,34 @@ import org.hibernate.boot.MetadataSources;
|
|||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.SQLServer2008Dialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-10529")
|
||||
@RequiresDialect(value = SQLServer2008Dialect.class)
|
||||
public class SQLServer2008NVarCharTypeTest extends BaseUnitTestCase {
|
||||
@RequiresDialect(value = SQLServerDialect.class, version = 10)
|
||||
public class SQLServer2008NVarCharTypeTest {
|
||||
private StandardServiceRegistry ssr;
|
||||
private MetadataImplementor metadata;
|
||||
private SchemaExport schemaExport;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ssr = new StandardServiceRegistryBuilder().build();
|
||||
schemaExport = createSchemaExport( new Class[] {MyEntity.class} );
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
schemaExport.drop( EnumSet.of( TargetType.DATABASE ), metadata );
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Column;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.net.URL;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
|
@ -50,14 +50,14 @@ public class TimeAndTimestampTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
Event event = new Event();
|
||||
event.id = 1L;
|
||||
event.timeValue = new Time( 1000 );
|
||||
event.timestampValue = new Timestamp( 45678 );
|
||||
event.timestampValue = new Timestamp( 45677 );
|
||||
|
||||
session.persist( event );
|
||||
} );
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
Event event = session.find( Event.class, 1L );
|
||||
assertEquals(1000, event.timeValue.getTime() % TimeUnit.DAYS.toMillis( 1 ));
|
||||
assertEquals(45678, event.timestampValue.getTime() % TimeUnit.DAYS.toMillis( 1 ));
|
||||
assertEquals(45677, event.timestampValue.getTime() % TimeUnit.DAYS.toMillis( 1 ));
|
||||
} );
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.type;
|
||||
package org.hibernate.orm.test.type;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -22,12 +22,12 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.ZonedDateTimeType;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
@ -96,26 +96,36 @@ public class ZonedDateTimeTest extends AbstractJavaTimeTypeTest<ZonedDateTime, Z
|
|||
.add( 1900, 1, 1, 0, 19, 32, 0, "Europe/Amsterdam", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 32, 0, "GMT+00:19:32", ZONE_AMSTERDAM )
|
||||
.add( 1900, 1, 1, 0, 19, 32, 0, "Europe/Amsterdam", ZONE_AMSTERDAM )
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "GMT+00:00", ZONE_OSLO )
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "Europe/Oslo", ZONE_OSLO )
|
||||
.add( 1900, 1, 1, 0, 9, 20, 0, "GMT+00:09:21", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 9, 20, 0, "Europe/Paris", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, "GMT+00:19:32", ZONE_PARIS )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, "GMT+00:19:32", ZONE_AMSTERDAM )
|
||||
.add( 1900, 1, 1, 0, 19, 31, 0, "Europe/Amsterdam", ZONE_AMSTERDAM )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb cannot store values equal to epoch exactly, or less, in a timestamp.
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
// Affected by HHH-13266 (JDK-8061577)
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "GMT+00:00", ZONE_OSLO )
|
||||
.add( 1892, 1, 1, 0, 0, 0, 0, "Europe/Oslo", ZONE_OSLO )
|
||||
)
|
||||
.skippedForDialects(
|
||||
// MySQL/Mariadb/Sybase cannot store dates in 1600 in a timestamp.
|
||||
Arrays.asList( MySQLDialect.class, MariaDBDialect.class, SybaseDialect.class ),
|
||||
dialect -> dialect instanceof MySQLDialect || dialect instanceof MariaDBDialect || dialect instanceof SybaseDialect
|
||||
|| dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b
|
||||
.add( 1600, 1, 1, 0, 0, 0, 0, "GMT+00:19:32", ZONE_AMSTERDAM )
|
||||
.add( 1600, 1, 1, 0, 0, 0, 0, "Europe/Amsterdam", ZONE_AMSTERDAM )
|
||||
)
|
||||
// HHH-13379: DST end (where Timestamp becomes ambiguous, see JDK-4312621)
|
||||
// => This used to work correctly in 5.4.1.Final and earlier
|
||||
.add( 2018, 10, 28, 2, 0, 0, 0, "+01:00", ZONE_PARIS )
|
||||
.skippedForDialects(
|
||||
dialect -> dialect instanceof H2Dialect && ( (H2Dialect) dialect ).hasDstBug(),
|
||||
b -> b.add( 2018, 10, 28, 2, 0, 0, 0, "+01:00", ZONE_PARIS )
|
||||
.add( 2018, 4, 1, 2, 0, 0, 0, "+12:00", ZONE_AUCKLAND )
|
||||
)
|
||||
// => This has never worked correctly, unless the JDBC timezone was set to UTC
|
||||
.withForcedJdbcTimezone( "UTC", b -> b
|
||||
.add( 2018, 10, 28, 2, 0, 0, 0, "+02:00", ZONE_PARIS )
|
|
@ -50,33 +50,34 @@ public class TypeOverrideTest extends BaseSessionFactoryFunctionalTest {
|
|||
|
||||
@Test
|
||||
public void testStandardBasicSqlTypeDescriptor() {
|
||||
final Dialect dialect = getMetadata().getDatabase().getDialect();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = getMetadata().getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry();
|
||||
// no override
|
||||
assertSame( IntegerJdbcTypeDescriptor.INSTANCE, jdbcTypeRegistry.getDescriptor( Types.INTEGER ) );
|
||||
|
||||
// A few dialects explicitly override BlobTypeDescriptor.DEFAULT
|
||||
if ( CockroachDialect.class.isInstance( getDialect() ) ) {
|
||||
if ( CockroachDialect.class.isInstance( dialect ) ) {
|
||||
assertSame(
|
||||
VarbinaryJdbcTypeDescriptor.INSTANCE,
|
||||
jdbcTypeRegistry.getDescriptor( Types.BLOB )
|
||||
);
|
||||
}
|
||||
else if ( PostgreSQLDialect.class.isInstance( getDialect() ) ) {
|
||||
else if ( PostgreSQLDialect.class.isInstance( dialect ) ) {
|
||||
assertSame(
|
||||
BlobJdbcTypeDescriptor.BLOB_BINDING,
|
||||
jdbcTypeRegistry.getDescriptor( Types.BLOB )
|
||||
);
|
||||
}
|
||||
else if ( SybaseDialect.class.isInstance( getDialect() ) ) {
|
||||
else if ( SybaseDialect.class.isInstance( dialect ) ) {
|
||||
assertSame(
|
||||
BlobJdbcTypeDescriptor.PRIMITIVE_ARRAY_BINDING,
|
||||
jdbcTypeRegistry.getDescriptor( Types.BLOB )
|
||||
);
|
||||
}
|
||||
else if ( AbstractHANADialect.class.isInstance( getDialect() ) ) {
|
||||
else if ( AbstractHANADialect.class.isInstance( dialect ) ) {
|
||||
assertSame(
|
||||
( (AbstractHANADialect) getDialect() ).getBlobTypeDescriptor(),
|
||||
( (AbstractHANADialect) dialect ).getBlobTypeDescriptor(),
|
||||
jdbcTypeRegistry.getDescriptor( Types.BLOB )
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.dialect.NationalizationSupport;
|
|||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.query.FetchClauseType;
|
||||
|
||||
/**
|
||||
|
@ -269,7 +270,7 @@ abstract public class DialectFeatureChecks {
|
|||
|
||||
public static class SupportsTimezoneTypes implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
return dialect.supportsTimezoneTypes();
|
||||
return dialect.getTimeZoneSupport() == TimeZoneSupport.NATIVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue