Skip to content

Commit

Permalink
Introduce option to configure how to store java.time.Duration
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Mar 25, 2022
1 parent 7020a1a commit 6801ff0
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 7 deletions.
Expand Up @@ -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.
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -415,6 +416,7 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo

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 );
Expand Down Expand Up @@ -1188,6 +1190,11 @@ public int getPreferredSqlTypeCodeForBoolean() {
return preferredSqlTypeCodeForBoolean;
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return preferredSqlTypeCodeForDuration;
}

@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return defaultTimeZoneStorageStrategy;
Expand Down
Expand Up @@ -437,6 +437,11 @@ public int getPreferredSqlTypeCodeForBoolean() {
return delegate.getPreferredSqlTypeCodeForBoolean();
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return delegate.getPreferredSqlTypeCodeForDuration();
}

@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
return delegate.getDefaultTimeZoneStorageStrategy();
Expand Down
Expand Up @@ -55,6 +55,10 @@ default int getPreferredSqlTypeCodeForBoolean() {
return ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( getBootstrapContext().getServiceRegistry() );
}

default int getPreferredSqlTypeCodeForDuration() {
return ConfigurationHelper.getPreferredSqlTypeCodeForDuration( getBootstrapContext().getServiceRegistry() );
}

TypeDefinitionRegistry getTypeDefinitionRegistry();

/**
Expand Down
Expand Up @@ -300,6 +300,8 @@ default boolean isCollectionsInDefaultFetchGroupEnabled() {

int getPreferredSqlTypeCodeForBoolean();

int getPreferredSqlTypeCodeForDuration();

TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy();

FormatMapper getJsonFormatMapper();
Expand Down
Expand Up @@ -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:
Expand Down
Expand Up @@ -214,6 +214,11 @@ public int getPreferredSqlTypeCodeForBoolean() {
return buildingContext.getPreferredSqlTypeCodeForBoolean();
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return buildingContext.getPreferredSqlTypeCodeForDuration();
}

@Override
public boolean isNationalized() {
return isNationalized;
Expand Down
Expand Up @@ -20,6 +20,7 @@
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.
Expand Down Expand Up @@ -528,4 +529,12 @@ public static synchronized int getPreferredSqlTypeCodeForBoolean(StandardService
.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
);
}

}
Expand Up @@ -679,6 +679,11 @@ public int getPreferredSqlTypeCodeForBoolean() {
return getBuildingContext().getPreferredSqlTypeCodeForBoolean();
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return getBuildingContext().getPreferredSqlTypeCodeForDuration();
}

@Override
public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
if ( timeZoneStorageType != null ) {
Expand Down
Expand Up @@ -584,7 +584,12 @@ public int getPreferredSqlTypeCodeForBoolean() {
return creationContext.getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public int getPreferredSqlTypeCodeForDuration() {
return creationContext.getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForDuration();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FromClauseAccess

@Override
Expand Down
Expand Up @@ -54,7 +54,7 @@ public DurationJavaType() {

@Override
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( SqlTypes.INTERVAL_SECOND );
return context.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( context.getPreferredSqlTypeCodeForDuration() );
}

@Override
Expand Down
Expand Up @@ -11,6 +11,7 @@
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;
Expand Down Expand Up @@ -72,6 +73,16 @@ default int getPreferredSqlTypeCodeForBoolean() {
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)
*/
Expand Down
Expand Up @@ -351,11 +351,6 @@ private static class Scope implements Serializable {
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}

@Override
public int getPreferredSqlTypeCodeForBoolean() {
return SqlTypes.BOOLEAN;
}
};

public Scope(TypeConfiguration typeConfiguration) {
Expand Down

0 comments on commit 6801ff0

Please sign in to comment.