Allow configuring the preferred JDBC type for Instant
This commit is contained in:
parent
a9d1035806
commit
117e62195a
|
@ -392,6 +392,10 @@ Can also specify the name of the constant in `org.hibernate.type.SqlTypes` inste
|
|||
Global setting identifying the preferred JDBC type code for storing duration values.
|
||||
Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead.
|
||||
|
||||
`*hibernate.type.preferred_instant_jdbc_type*` (e.g. `93` for `java.sql.Types.TIMESTAMP` or `3003` for `org.hibernate.types.SqlTypes.TIMESTAMP_UTC` (default value))::
|
||||
Global setting identifying the preferred JDBC type code for storing instant values.
|
||||
Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead.
|
||||
|
||||
==== Bean Validation options
|
||||
`*jakarta.persistence.validation.factory*` (e.g. `jakarta.validation.ValidationFactory` implementation)::
|
||||
Specify the `javax.validation.ValidationFactory` implementation to use for Bean Validation.
|
||||
|
|
|
@ -214,6 +214,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
private final int preferredSqlTypeCodeForBoolean;
|
||||
private final int preferredSqlTypeCodeForDuration;
|
||||
private final int preferredSqlTypeCodeForUuid;
|
||||
private final int preferredSqlTypeCodeForInstant;
|
||||
private final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
|
||||
|
||||
// Caching
|
||||
|
@ -419,6 +420,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
|
||||
this.preferredSqlTypeCodeForDuration = ConfigurationHelper.getPreferredSqlTypeCodeForDuration( serviceRegistry );
|
||||
this.preferredSqlTypeCodeForUuid = ConfigurationHelper.getPreferredSqlTypeCodeForUuid( serviceRegistry );
|
||||
this.preferredSqlTypeCodeForInstant = ConfigurationHelper.getPreferredSqlTypeCodeForInstant( serviceRegistry );
|
||||
this.defaultTimeZoneStorageStrategy = context.getMetadataBuildingOptions().getDefaultTimeZoneStorage();
|
||||
|
||||
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
|
||||
|
@ -1202,6 +1204,11 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
return preferredSqlTypeCodeForUuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForInstant() {
|
||||
return preferredSqlTypeCodeForInstant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return defaultTimeZoneStorageStrategy;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.boot.model.process.spi;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collection;
|
||||
|
@ -448,6 +449,22 @@ public class MetadataBuildingProcess {
|
|||
ZonedDateTime.class.getName()
|
||||
);
|
||||
}
|
||||
final int preferredSqlTypeCodeForInstant = ConfigurationHelper.getPreferredSqlTypeCodeForInstant( bootstrapContext.getServiceRegistry() );
|
||||
if ( preferredSqlTypeCodeForInstant != SqlTypes.TIMESTAMP_UTC ) {
|
||||
final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry();
|
||||
final BasicTypeRegistry basicTypeRegistry = typeConfiguration.getBasicTypeRegistry();
|
||||
final BasicType<?> instantType = new NamedBasicTypeImpl<>(
|
||||
javaTypeRegistry.getDescriptor( Instant.class ),
|
||||
jdbcTypeRegistry.getDescriptor( preferredSqlTypeCodeForInstant ),
|
||||
"instant"
|
||||
);
|
||||
basicTypeRegistry.register(
|
||||
instantType,
|
||||
"org.hibernate.type.InstantType",
|
||||
Instant.class.getSimpleName(),
|
||||
Instant.class.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFallbackIfNecessary(
|
||||
|
|
|
@ -447,6 +447,11 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
|||
return delegate.getPreferredSqlTypeCodeForUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForInstant() {
|
||||
return delegate.getPreferredSqlTypeCodeForInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
return delegate.getDefaultTimeZoneStorageStrategy();
|
||||
|
|
|
@ -63,6 +63,10 @@ public interface MetadataBuildingContext {
|
|||
return ConfigurationHelper.getPreferredSqlTypeCodeForUuid( getBootstrapContext().getServiceRegistry() );
|
||||
}
|
||||
|
||||
default int getPreferredSqlTypeCodeForInstant() {
|
||||
return ConfigurationHelper.getPreferredSqlTypeCodeForInstant( getBootstrapContext().getServiceRegistry() );
|
||||
}
|
||||
|
||||
TypeDefinitionRegistry getTypeDefinitionRegistry();
|
||||
|
||||
/**
|
||||
|
|
|
@ -304,6 +304,8 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
|||
|
||||
int getPreferredSqlTypeCodeForUuid();
|
||||
|
||||
int getPreferredSqlTypeCodeForInstant();
|
||||
|
||||
TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy();
|
||||
|
||||
FormatMapper getJsonFormatMapper();
|
||||
|
|
|
@ -2514,6 +2514,20 @@ public interface AvailableSettings {
|
|||
*/
|
||||
String PREFERRED_DURATION_JDBC_TYPE = "hibernate.type.preferred_duration_jdbc_type";
|
||||
|
||||
/**
|
||||
* Specifies the preferred JDBC type for storing instant values. When no
|
||||
* type is explicitly specified, {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC} is used.
|
||||
*
|
||||
* Can be overridden locally using {@link org.hibernate.annotations.JdbcType},
|
||||
* {@link org.hibernate.annotations.JdbcTypeCode} and friends
|
||||
*
|
||||
* Can also specify the name of the constant in {@link org.hibernate.type.SqlTypes} instead. E.g.
|
||||
* {@code hibernate.type.preferred_instant_jdbc_type=TIMESTAMP}
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
String PREFERRED_INSTANT_JDBC_TYPE = "hibernate.type.preferred_instant_jdbc_type";
|
||||
|
||||
/**
|
||||
* Specifies a {@link org.hibernate.type.FormatMapper} used for for JSON serialization
|
||||
* and deserialization, either:
|
||||
|
|
|
@ -226,6 +226,11 @@ public class BasicValueBinder implements JdbcTypeIndicators {
|
|||
return buildingContext.getPreferredSqlTypeCodeForUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForInstant() {
|
||||
return buildingContext.getPreferredSqlTypeCodeForInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNationalized() {
|
||||
return isNationalized;
|
||||
|
|
|
@ -545,6 +545,14 @@ public final class ConfigurationHelper {
|
|||
);
|
||||
}
|
||||
|
||||
public static synchronized int getPreferredSqlTypeCodeForInstant(StandardServiceRegistry serviceRegistry) {
|
||||
return serviceRegistry.getService( ConfigurationService.class ).getSetting(
|
||||
AvailableSettings.PREFERRED_INSTANT_JDBC_TYPE,
|
||||
TypeCodeConverter.INSTANCE,
|
||||
SqlTypes.TIMESTAMP_UTC
|
||||
);
|
||||
}
|
||||
|
||||
private static class TypeCodeConverter implements ConfigurationService.Converter<Integer> {
|
||||
|
||||
public static final TypeCodeConverter INSTANCE = new TypeCodeConverter();
|
||||
|
|
|
@ -689,6 +689,11 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
|||
return getBuildingContext().getPreferredSqlTypeCodeForUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForInstant() {
|
||||
return getBuildingContext().getPreferredSqlTypeCodeForInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
|
||||
if ( timeZoneStorageType != null ) {
|
||||
|
|
|
@ -454,7 +454,7 @@ public final class StandardBasicTypes {
|
|||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link Instant} to JDBC
|
||||
* {@link org.hibernate.type.SqlTypes#TIMESTAMP TIMESTAMP}.
|
||||
* {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC TIMESTAMP_UTC}.
|
||||
*/
|
||||
public static final BasicTypeReference<Instant> INSTANT = new BasicTypeReference<>(
|
||||
"instant",
|
||||
|
|
|
@ -68,7 +68,7 @@ public class InstantJavaType extends AbstractTemporalJavaType<Instant>
|
|||
|
||||
@Override
|
||||
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
|
||||
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( SqlTypes.TIMESTAMP_UTC );
|
||||
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( context.getPreferredSqlTypeCodeForInstant() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -84,7 +84,7 @@ public interface JdbcTypeIndicators {
|
|||
}
|
||||
|
||||
/**
|
||||
* When mapping a uuid type to the database what is the preferred SQL type code to use?
|
||||
* When mapping an uuid type to the database what is the preferred SQL type code to use?
|
||||
* <p/>
|
||||
* Specifically names the key into the
|
||||
* {@link JdbcTypeRegistry}.
|
||||
|
@ -93,6 +93,16 @@ public interface JdbcTypeIndicators {
|
|||
return SqlTypes.UUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* When mapping an instant type to the database what is the preferred SQL type code to use?
|
||||
* <p/>
|
||||
* Specifically names the key into the
|
||||
* {@link JdbcTypeRegistry}.
|
||||
*/
|
||||
default int getPreferredSqlTypeCodeForInstant() {
|
||||
return SqlTypes.TIMESTAMP_UTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for resolutions based on column length. E.g. choosing between a VARCHAR (String) and a CHAR(1) (Character/char)
|
||||
*/
|
||||
|
|
|
@ -292,6 +292,16 @@ The migration to `uuid` might require a migration expression like `cast(old as u
|
|||
|
||||
To retain backwards compatibility, configure the setting `hibernate.type.preferred_uuid_jdbc_type` to `BINARY`.
|
||||
|
||||
=== Instant mapping changes
|
||||
|
||||
Instant now maps to the type code `SqlType.TIMESTAMP_UTC` by default, which maps to the SQL type `timestamp with time zone`
|
||||
if possible, and falls back to `timestamp`.
|
||||
Due to this change, schema validation errors could occur on some databases.
|
||||
|
||||
The migration to `timestamp with time zone` might require a migration expression like `cast(old as timestamp with time zone)`.
|
||||
|
||||
To retain backwards compatibility, configure the setting `hibernate.type.preferred_instant_jdbc_type` to `TIMESTAMP`.
|
||||
|
||||
[[query]]
|
||||
== Query
|
||||
|
||||
|
|
Loading…
Reference in New Issue