Introduce option to configure how to store java.time.Duration

This commit is contained in:
Christian Beikov 2022-03-21 17:59:51 +01:00
parent 7020a1a563
commit 6801ff0f26
13 changed files with 66 additions and 7 deletions

View File

@ -383,6 +383,9 @@ This setting applies to Oracle Dialect only, and it specifies whether `byte[]` o
`*hibernate.type.preferred_boolean_jdbc_type_code*` (e.g. `-7` for `java.sql.Types.BIT`)::
Global setting identifying the preferred JDBC type code for storing boolean values. The fallback is to ask the Dialect.
`*hibernate.type.preferred_duration_jdbc_type_code*` (e.g. `2` for `java.sql.Types.NUMERIC` or `3` for `java.sql.Types.DECIMAL`)::
Global setting identifying the preferred JDBC type code for storing duration values. The fallback is `3100` for `org.hibernate.types.SqlTypes.INTERVAL_SECOND`.
==== Bean Validation options
`*jakarta.persistence.validation.factory*` (e.g. `jakarta.validation.ValidationFactory` implementation)::
Specify the `javax.validation.ValidationFactory` implementation to use for Bean Validation.

View File

@ -212,6 +212,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private Boolean useOfJdbcNamedParametersEnabled;
private boolean namedQueryStartupCheckingEnabled;
private final int preferredSqlTypeCodeForBoolean;
private final int preferredSqlTypeCodeForDuration;
private final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy;
// Caching
@ -415,6 +416,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );
this.preferredSqlTypeCodeForDuration = ConfigurationHelper.getPreferredSqlTypeCodeForDuration( serviceRegistry );
this.defaultTimeZoneStorageStrategy = context.getMetadataBuildingOptions().getDefaultTimeZoneStorage();
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
@ -1188,6 +1190,11 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
return preferredSqlTypeCodeForBoolean;
}
@Override
public int getPreferredSqlTypeCodeForDuration() {
return preferredSqlTypeCodeForDuration;
}
@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return defaultTimeZoneStorageStrategy;

View File

@ -437,6 +437,11 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
return delegate.getPreferredSqlTypeCodeForBoolean();
}
@Override
public int getPreferredSqlTypeCodeForDuration() {
return delegate.getPreferredSqlTypeCodeForDuration();
}
@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return delegate.getDefaultTimeZoneStorageStrategy();

View File

@ -55,6 +55,10 @@ public interface MetadataBuildingContext {
return ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( getBootstrapContext().getServiceRegistry() );
}
default int getPreferredSqlTypeCodeForDuration() {
return ConfigurationHelper.getPreferredSqlTypeCodeForDuration( getBootstrapContext().getServiceRegistry() );
}
TypeDefinitionRegistry getTypeDefinitionRegistry();
/**

View File

@ -300,6 +300,8 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
int getPreferredSqlTypeCodeForBoolean();
int getPreferredSqlTypeCodeForDuration();
TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy();
FormatMapper getJsonFormatMapper();

View File

@ -2483,6 +2483,14 @@ public interface AvailableSettings {
*/
String PREFERRED_BOOLEAN_JDBC_TYPE_CODE = "hibernate.type.preferred_boolean_jdbc_type_code";
/**
* Specifies the preferred JDBC type code for storing duration values. When no
* type code is explicitly specified, {@link org.hibernate.type.SqlTypes#INTERVAL_SECOND} is used.
*
* @since 6.0
*/
String PREFERRED_DURATION_JDBC_TYPE_CODE = "hibernate.type.preferred_duration_jdbc_type_code";
/**
* Specifies a {@link org.hibernate.type.FormatMapper} used for for JSON serialization
* and deserialization, either:

View File

@ -214,6 +214,11 @@ public class BasicValueBinder implements JdbcTypeIndicators {
return buildingContext.getPreferredSqlTypeCodeForBoolean();
}
@Override
public int getPreferredSqlTypeCodeForDuration() {
return buildingContext.getPreferredSqlTypeCodeForDuration();
}
@Override
public boolean isNationalized() {
return isNationalized;

View File

@ -20,6 +20,7 @@ import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.type.SqlTypes;
/**
* Collection of helper methods for dealing with configuration settings.
@ -528,4 +529,12 @@ public final class ConfigurationHelper {
.getPreferredSqlTypeCodeForBoolean();
}
public static synchronized int getPreferredSqlTypeCodeForDuration(StandardServiceRegistry serviceRegistry) {
return serviceRegistry.getService( ConfigurationService.class ).getSetting(
AvailableSettings.PREFERRED_DURATION_JDBC_TYPE_CODE,
StandardConverters.INTEGER,
SqlTypes.INTERVAL_SECOND
);
}
}

View File

@ -679,6 +679,11 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
return getBuildingContext().getPreferredSqlTypeCodeForBoolean();
}
@Override
public int getPreferredSqlTypeCodeForDuration() {
return getBuildingContext().getPreferredSqlTypeCodeForDuration();
}
@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
if ( timeZoneStorageType != null ) {

View File

@ -584,7 +584,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
return creationContext.getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public int getPreferredSqlTypeCodeForDuration() {
return creationContext.getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForDuration();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FromClauseAccess
@Override

View File

@ -54,7 +54,7 @@ public class DurationJavaType extends AbstractClassJavaType<Duration> {
@Override
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( SqlTypes.INTERVAL_SECOND );
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( context.getPreferredSqlTypeCodeForDuration() );
}
@Override

View File

@ -11,6 +11,7 @@ import jakarta.persistence.EnumType;
import jakarta.persistence.TemporalType;
import org.hibernate.TimeZoneStorageStrategy;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
@ -72,6 +73,16 @@ public interface JdbcTypeIndicators {
return Types.BOOLEAN;
}
/**
* When mapping a duration type to the database what is the preferred SQL type code to use?
* <p/>
* Specifically names the key into the
* {@link JdbcTypeRegistry}.
*/
default int getPreferredSqlTypeCodeForDuration() {
return SqlTypes.INTERVAL_SECOND;
}
/**
* Useful for resolutions based on column length. E.g. choosing between a VARCHAR (String) and a CHAR(1) (Character/char)
*/

View File

@ -351,11 +351,6 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public int getPreferredSqlTypeCodeForBoolean() {
return SqlTypes.BOOLEAN;
}
};
public Scope(TypeConfiguration typeConfiguration) {