Fix test failures on nightly test pipeline
This commit is contained in:
parent
ea7c8c6836
commit
7ec3667802
|
@ -11,6 +11,13 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
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.ZonedDateTime;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -21,6 +28,7 @@ import org.hibernate.LockOptions;
|
||||||
import org.hibernate.boot.model.FunctionContributions;
|
import org.hibernate.boot.model.FunctionContributions;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
import org.hibernate.dialect.DB2Dialect;
|
||||||
|
import org.hibernate.dialect.DB2GetObjectExtractor;
|
||||||
import org.hibernate.dialect.DB2StructJdbcType;
|
import org.hibernate.dialect.DB2StructJdbcType;
|
||||||
import org.hibernate.dialect.DatabaseVersion;
|
import org.hibernate.dialect.DatabaseVersion;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
@ -82,15 +90,24 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNo
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.JavaObjectType;
|
import org.hibernate.type.JavaObjectType;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.CharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.CharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.DecimalJdbcType;
|
import org.hibernate.type.descriptor.jdbc.DecimalJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.InstantJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalDateJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalDateTimeJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType;
|
import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.OffsetDateTimeJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.OffsetTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.ZonedDateTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
|
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
|
||||||
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
||||||
|
@ -805,6 +822,12 @@ public class DB2LegacyDialect extends Dialect {
|
||||||
return "values current timestamp";
|
return "values current timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// DB2 does truncation
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrentTimestampSelectStringCallable() {
|
public boolean isCurrentTimestampSelectStringCallable() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -877,6 +900,49 @@ public class DB2LegacyDialect extends Dialect {
|
||||||
.getDescriptor( Object.class )
|
.getDescriptor( Object.class )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typeContributions.contributeJdbcType( new InstantJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, Instant.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalDateJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalDate.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new OffsetDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, OffsetDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new OffsetTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, OffsetTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new ZonedDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, ZonedDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -318,6 +318,11 @@ public class DerbyLegacyDialect extends Dialect {
|
||||||
return 52;
|
return 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultTimestampPrecision() {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
|
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
|
||||||
super.initializeFunctionRegistry(functionContributions);
|
super.initializeFunctionRegistry(functionContributions);
|
||||||
|
|
|
@ -723,6 +723,12 @@ public class HSQLLegacyDialect extends Dialect {
|
||||||
return "call current_timestamp";
|
return "call current_timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// HSQLDB does truncation
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For HSQLDB 2.0, this is a copy of the base class implementation.
|
* For HSQLDB 2.0, this is a copy of the base class implementation.
|
||||||
* For HSQLDB 1.8, only READ_UNCOMMITTED is supported.
|
* For HSQLDB 1.8, only READ_UNCOMMITTED is supported.
|
||||||
|
|
|
@ -179,6 +179,12 @@ public class MariaDBLegacyDialect extends MySQLLegacyDialect {
|
||||||
return getVersion().isSameOrAfter( 10, 2 );
|
return getVersion().isSameOrAfter( 10, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// See https://jira.mariadb.org/browse/MDEV-16991
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
||||||
return InnoDBStorageEngine.INSTANCE;
|
return InnoDBStorageEngine.INSTANCE;
|
||||||
|
|
|
@ -376,6 +376,11 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
return super.castPattern( from, to );
|
return super.castPattern( from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultTimestampPrecision() {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
public int getDefaultDecimalPrecision() {
|
public int getDefaultDecimalPrecision() {
|
||||||
//the maximum on HANA
|
//the maximum on HANA
|
||||||
return 34;
|
return 34;
|
||||||
|
|
|
@ -11,6 +11,13 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
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.ZonedDateTime;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -74,15 +81,24 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNo
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.JavaObjectType;
|
import org.hibernate.type.JavaObjectType;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.CharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.CharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.DecimalJdbcType;
|
import org.hibernate.type.descriptor.jdbc.DecimalJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.InstantJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalDateJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalDateTimeJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LocalTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType;
|
import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.OffsetDateTimeJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.OffsetTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.ZonedDateTimeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
|
import org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType;
|
||||||
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
||||||
|
@ -888,6 +904,12 @@ public class DB2Dialect extends Dialect {
|
||||||
return "values current timestamp";
|
return "values current timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// DB2 does truncation
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrentTimestampSelectStringCallable() {
|
public boolean isCurrentTimestampSelectStringCallable() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -960,6 +982,49 @@ public class DB2Dialect extends Dialect {
|
||||||
.getDescriptor( Object.class )
|
.getDescriptor( Object.class )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typeContributions.contributeJdbcType( new InstantJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, Instant.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalDateJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalDate.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new LocalTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, LocalTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new OffsetDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, OffsetDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new OffsetTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, OffsetTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
typeContributions.contributeJdbcType( new ZonedDateTimeJdbcType() {
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new DB2GetObjectExtractor<>( javaType, this, ZonedDateTime.class );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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 java.sql.CallableStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JavaTimeJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.internal.GetObjectExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of the {@link GetObjectExtractor} that catches a {@link NullPointerException},
|
||||||
|
* because the DB2 JDBC driver runs into that exception when trying to access a {@code null} value
|
||||||
|
* with the {@code getObject(int, Class)} and {@code getObject(String, Class)} methods.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class DB2GetObjectExtractor<T> extends GetObjectExtractor<T> {
|
||||||
|
public DB2GetObjectExtractor(
|
||||||
|
JavaType<T> javaType,
|
||||||
|
JavaTimeJdbcType jdbcType,
|
||||||
|
Class<?> baseClass) {
|
||||||
|
super( javaType, jdbcType, baseClass );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
|
||||||
|
try {
|
||||||
|
return super.doExtract( rs, paramIndex, options );
|
||||||
|
}
|
||||||
|
catch (NullPointerException ex) {
|
||||||
|
final Object object = rs.getObject( paramIndex );
|
||||||
|
if ( object == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T doExtract(CallableStatement statement, int paramIndex, WrapperOptions options) throws SQLException {
|
||||||
|
try {
|
||||||
|
return super.doExtract( statement, paramIndex, options );
|
||||||
|
}
|
||||||
|
catch (NullPointerException ex) {
|
||||||
|
final Object object = statement.getObject( paramIndex );
|
||||||
|
if ( object == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
||||||
|
try {
|
||||||
|
return super.doExtract( statement, name, options );
|
||||||
|
}
|
||||||
|
catch (NullPointerException ex) {
|
||||||
|
final Object object = statement.getObject( name );
|
||||||
|
if ( object == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -307,6 +307,11 @@ public class DerbyDialect extends Dialect {
|
||||||
return 52;
|
return 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultTimestampPrecision() {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
|
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
|
||||||
super.initializeFunctionRegistry(functionContributions);
|
super.initializeFunctionRegistry(functionContributions);
|
||||||
|
|
|
@ -4779,6 +4779,15 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
||||||
return 6; //microseconds!
|
return 6; //microseconds!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this dialect round a temporal when converting from a precision higher to a lower one?
|
||||||
|
*
|
||||||
|
* @return true if rounding is applied, false if truncation is applied
|
||||||
|
*/
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the default precision for a generated
|
* This is the default precision for a generated
|
||||||
* column mapped to a Java {@link Float} or
|
* column mapped to a Java {@link Float} or
|
||||||
|
|
|
@ -583,6 +583,12 @@ public class HSQLDialect extends Dialect {
|
||||||
return "values current_timestamp";
|
return "values current_timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// HSQLDB does truncation
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCommentOn() {
|
public boolean supportsCommentOn() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -179,6 +179,12 @@ public class MariaDBDialect extends MySQLDialect {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRoundTemporalOnOverflow() {
|
||||||
|
// See https://jira.mariadb.org/browse/MDEV-16991
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
||||||
return InnoDBStorageEngine.INSTANCE;
|
return InnoDBStorageEngine.INSTANCE;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeFormatterBuilder;
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.time.temporal.Temporal;
|
import java.time.temporal.Temporal;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
@ -447,6 +448,32 @@ public final class DateTimeUtils {
|
||||||
appender.appendSql( LOCAL_TIME_FORMAT.get().format( calendar.getTime() ) );
|
appender.appendSql( LOCAL_TIME_FORMAT.get().format( calendar.getTime() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the same conversion that databases do when they encounter a timestamp with a higher precision
|
||||||
|
* than what is supported by a column, which is to round the excess fractions.
|
||||||
|
*/
|
||||||
|
public static <T extends Temporal> T adjustToDefaultPrecision(T temporal, Dialect d) {
|
||||||
|
return adjustToPrecision( temporal, d.getDefaultTimestampPrecision(), d );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Temporal> T adjustToPrecision(T temporal, int precision, Dialect d) {
|
||||||
|
return d.doesRoundTemporalOnOverflow()
|
||||||
|
? roundToSecondPrecision( temporal, precision )
|
||||||
|
: truncateToPrecision( temporal, precision );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Temporal> T truncateToPrecision(T temporal, int precision) {
|
||||||
|
if ( precision >= 9 || !temporal.isSupported( ChronoField.NANO_OF_SECOND ) ) {
|
||||||
|
return temporal;
|
||||||
|
}
|
||||||
|
final long factor = pow10( 9 - precision );
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) temporal.with(
|
||||||
|
ChronoField.NANO_OF_SECOND,
|
||||||
|
temporal.get( ChronoField.NANO_OF_SECOND ) / factor * factor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the same conversion that databases do when they encounter a timestamp with a higher precision
|
* Do the same conversion that databases do when they encounter a timestamp with a higher precision
|
||||||
* than what is supported by a column, which is to round the excess fractions.
|
* than what is supported by a column, which is to round the excess fractions.
|
||||||
|
@ -464,6 +491,12 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Temporal> T roundToSecondPrecision(T temporal, int precision) {
|
public static <T extends Temporal> T roundToSecondPrecision(T temporal, int precision) {
|
||||||
|
if ( precision == 0 ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return temporal.get( ChronoField.NANO_OF_SECOND ) >= 500_000_000L
|
||||||
|
? (T) temporal.plus( 1, ChronoUnit.SECONDS ).with( ChronoField.NANO_OF_SECOND, 0L )
|
||||||
|
: (T) temporal.with( ChronoField.NANO_OF_SECOND, 0L );
|
||||||
|
}
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (T) temporal.with(
|
return (T) temporal.with(
|
||||||
ChronoField.NANO_OF_SECOND,
|
ChronoField.NANO_OF_SECOND,
|
||||||
|
@ -472,9 +505,9 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long roundToPrecision(int nano, int precision) {
|
public static long roundToPrecision(int nano, int precision) {
|
||||||
assert precision < 9 : "Precision (scale) should be less-than 9 - " + precision;
|
assert precision > 0 : "Can't round fractional seconds to less-than 0";
|
||||||
if ( precision == 0 ) {
|
if ( precision >= 9 ) {
|
||||||
return 0;
|
return nano;
|
||||||
}
|
}
|
||||||
final int precisionMask = pow10( 9 - precision );
|
final int precisionMask = pow10( 9 - precision );
|
||||||
final int nanosToRound = nano % precisionMask;
|
final int nanosToRound = nano % precisionMask;
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
import org.hibernate.generator.EventType;
|
import org.hibernate.generator.EventType;
|
||||||
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
|
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
|
||||||
|
import org.hibernate.id.insert.AbstractReturningDelegate;
|
||||||
|
import org.hibernate.id.insert.AbstractSelectingDelegate;
|
||||||
import org.hibernate.id.insert.UniqueKeySelectingDelegate;
|
import org.hibernate.id.insert.UniqueKeySelectingDelegate;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.sql.model.MutationType;
|
import org.hibernate.sql.model.MutationType;
|
||||||
|
@ -73,7 +75,7 @@ public class MutationDelegateIdentityTest {
|
||||||
assertThat( entity.getName() ).isNull();
|
assertThat( entity.getName() ).isNull();
|
||||||
|
|
||||||
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
inspector.assertExecutedCount( delegate != null ? 1 : 2 );
|
inspector.assertExecutedCount( delegate instanceof AbstractReturningDelegate ? 1 : 2 );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +99,9 @@ public class MutationDelegateIdentityTest {
|
||||||
|
|
||||||
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
inspector.assertExecutedCount(
|
inspector.assertExecutedCount(
|
||||||
delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
delegate instanceof AbstractSelectingDelegate
|
||||||
|
? 3
|
||||||
|
: delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -110,7 +114,7 @@ public class MutationDelegateIdentityTest {
|
||||||
MutationType.UPDATE
|
MutationType.UPDATE
|
||||||
);
|
);
|
||||||
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
||||||
final Integer id = scope.fromTransaction( session -> {
|
final Long id = scope.fromTransaction( session -> {
|
||||||
final IdentityAndValues entity = new IdentityAndValues();
|
final IdentityAndValues entity = new IdentityAndValues();
|
||||||
session.persist( entity );
|
session.persist( entity );
|
||||||
session.flush();
|
session.flush();
|
||||||
|
@ -154,7 +158,9 @@ public class MutationDelegateIdentityTest {
|
||||||
|
|
||||||
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
inspector.assertExecutedCount(
|
inspector.assertExecutedCount(
|
||||||
delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
delegate instanceof AbstractSelectingDelegate
|
||||||
|
? 3
|
||||||
|
: delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
||||||
);
|
);
|
||||||
|
|
||||||
final boolean shouldHaveRowId = delegate != null && delegate.supportsRowId()
|
final boolean shouldHaveRowId = delegate != null && delegate.supportsRowId()
|
||||||
|
@ -210,7 +216,7 @@ public class MutationDelegateIdentityTest {
|
||||||
);
|
);
|
||||||
if ( isUniqueKeyDelegate ) {
|
if ( isUniqueKeyDelegate ) {
|
||||||
inspector.assertNumberOfOccurrenceInQueryNoSpace( 1, "data", 1 );
|
inspector.assertNumberOfOccurrenceInQueryNoSpace( 1, "data", 1 );
|
||||||
inspector.assertNumberOfOccurrenceInQueryNoSpace( 1, "id_column", 0 );
|
inspector.assertNumberOfOccurrenceInQueryNoSpace( 1, "id_column", 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean shouldHaveRowId = delegate != null && delegate.supportsRowId()
|
final boolean shouldHaveRowId = delegate != null && delegate.supportsRowId()
|
||||||
|
@ -238,11 +244,11 @@ public class MutationDelegateIdentityTest {
|
||||||
public static class IdentityOnly {
|
public static class IdentityOnly {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public Integer getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +262,7 @@ public class MutationDelegateIdentityTest {
|
||||||
public static class IdentityAndValues {
|
public static class IdentityAndValues {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
@Generated( event = EventType.INSERT )
|
@Generated( event = EventType.INSERT )
|
||||||
@ColumnDefault( "'default_name'" )
|
@ColumnDefault( "'default_name'" )
|
||||||
|
@ -267,7 +273,7 @@ public class MutationDelegateIdentityTest {
|
||||||
|
|
||||||
private String data;
|
private String data;
|
||||||
|
|
||||||
public Integer getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +297,7 @@ public class MutationDelegateIdentityTest {
|
||||||
@Id
|
@Id
|
||||||
@Column( name = "id_column" )
|
@Column( name = "id_column" )
|
||||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
@Generated( event = EventType.INSERT )
|
@Generated( event = EventType.INSERT )
|
||||||
@ColumnDefault( "'default_name'" )
|
@ColumnDefault( "'default_name'" )
|
||||||
|
@ -302,7 +308,7 @@ public class MutationDelegateIdentityTest {
|
||||||
|
|
||||||
private String data;
|
private String data;
|
||||||
|
|
||||||
public Integer getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +332,7 @@ public class MutationDelegateIdentityTest {
|
||||||
@Id
|
@Id
|
||||||
@Column( name = "id_column" )
|
@Column( name = "id_column" )
|
||||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
@Generated( event = EventType.INSERT )
|
@Generated( event = EventType.INSERT )
|
||||||
@ColumnDefault( "'default_name'" )
|
@ColumnDefault( "'default_name'" )
|
||||||
|
@ -342,7 +348,7 @@ public class MutationDelegateIdentityTest {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.annotations.SourceType;
|
||||||
import org.hibernate.annotations.UpdateTimestamp;
|
import org.hibernate.annotations.UpdateTimestamp;
|
||||||
import org.hibernate.generator.EventType;
|
import org.hibernate.generator.EventType;
|
||||||
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
|
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
|
||||||
|
import org.hibernate.id.insert.AbstractSelectingDelegate;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.sql.model.MutationType;
|
import org.hibernate.sql.model.MutationType;
|
||||||
|
|
||||||
|
@ -70,7 +71,9 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
|
|
||||||
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
inspector.assertExecutedCount(
|
inspector.assertExecutedCount(
|
||||||
delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
delegate instanceof AbstractSelectingDelegate
|
||||||
|
? 3
|
||||||
|
: delegate != null && delegate.supportsArbitraryValues() ? 1 : 2
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -89,12 +92,28 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
assertThat( entity.getName() ).isEqualTo( "default_name" );
|
assertThat( entity.getName() ).isEqualTo( "default_name" );
|
||||||
assertThat( entity.getChildName() ).isEqualTo( "default_child_name" );
|
assertThat( entity.getChildName() ).isEqualTo( "default_child_name" );
|
||||||
|
|
||||||
|
final GeneratedValuesMutationDelegate delegate = getDelegate(
|
||||||
|
scope,
|
||||||
|
ChildEntity.class,
|
||||||
|
MutationType.INSERT
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( delegate instanceof AbstractSelectingDelegate ) {
|
||||||
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
|
assertThat( inspector.getSqlQueries().get( 2 ) ).contains( "insert" );
|
||||||
|
// Note: this is a current restriction, mutation delegates only retrieve generated values
|
||||||
|
// on the "root" table, and we expect other values to be read through a subsequent select
|
||||||
|
inspector.assertIsSelect( 3 );
|
||||||
|
inspector.assertExecutedCount( 4 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "insert" );
|
||||||
assertThat( inspector.getSqlQueries().get( 1 ) ).contains( "insert" );
|
assertThat( inspector.getSqlQueries().get( 1 ) ).contains( "insert" );
|
||||||
// Note: this is a current restriction, mutation delegates only retrieve generated values
|
// Note: this is a current restriction, mutation delegates only retrieve generated values
|
||||||
// on the "root" table, and we expect other values to be read through a subsequent select
|
// on the "root" table, and we expect other values to be read through a subsequent select
|
||||||
inspector.assertIsSelect( 2 );
|
inspector.assertIsSelect( 2 );
|
||||||
inspector.assertExecutedCount( 3 );
|
inspector.assertExecutedCount( 3 );
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +125,7 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
MutationType.UPDATE
|
MutationType.UPDATE
|
||||||
);
|
);
|
||||||
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
||||||
final Integer id = scope.fromTransaction( session -> {
|
final Long id = scope.fromTransaction( session -> {
|
||||||
final BaseEntity entity = new BaseEntity();
|
final BaseEntity entity = new BaseEntity();
|
||||||
session.persist( entity );
|
session.persist( entity );
|
||||||
session.flush();
|
session.flush();
|
||||||
|
@ -133,7 +152,7 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateChildEntity(SessionFactoryScope scope) {
|
public void testUpdateChildEntity(SessionFactoryScope scope) {
|
||||||
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
|
||||||
final Integer id = scope.fromTransaction( session -> {
|
final Long id = scope.fromTransaction( session -> {
|
||||||
final ChildEntity entity = new ChildEntity();
|
final ChildEntity entity = new ChildEntity();
|
||||||
session.persist( entity );
|
session.persist( entity );
|
||||||
session.flush();
|
session.flush();
|
||||||
|
@ -175,7 +194,7 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
public static class BaseEntity {
|
public static class BaseEntity {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
@Generated( event = EventType.INSERT )
|
@Generated( event = EventType.INSERT )
|
||||||
@ColumnDefault( "'default_name'" )
|
@ColumnDefault( "'default_name'" )
|
||||||
|
@ -187,7 +206,7 @@ public class MutationDelegateJoinedInheritanceTest {
|
||||||
@SuppressWarnings( "FieldCanBeLocal" )
|
@SuppressWarnings( "FieldCanBeLocal" )
|
||||||
private String data;
|
private String data;
|
||||||
|
|
||||||
public Integer getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.cfg.MappingSettings;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
import org.hibernate.dialect.DB2Dialect;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.HANADialect;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
import org.hibernate.dialect.OracleDialect;
|
||||||
import org.hibernate.dialect.SybaseDialect;
|
import org.hibernate.dialect.SybaseDialect;
|
||||||
import org.hibernate.mapping.BasicValue;
|
import org.hibernate.mapping.BasicValue;
|
||||||
|
@ -176,6 +177,7 @@ public class GlobalJavaTimeJdbcTypeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle drivers truncate fractional seconds from the LocalTime", matchSubTypes = true)
|
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle drivers truncate fractional seconds from the LocalTime", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA time type does not support fractional seconds", matchSubTypes = true)
|
||||||
void testLocalTime(SessionFactoryScope scope) {
|
void testLocalTime(SessionFactoryScope scope) {
|
||||||
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||||
final LocalTime startTime = roundToDefaultPrecision( LocalTime.now(), dialect );
|
final LocalTime startTime = roundToDefaultPrecision( LocalTime.now(), dialect );
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.cfg.MappingSettings;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
import org.hibernate.dialect.DB2Dialect;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.HANADialect;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
import org.hibernate.dialect.OracleDialect;
|
||||||
import org.hibernate.dialect.SybaseDialect;
|
import org.hibernate.dialect.SybaseDialect;
|
||||||
import org.hibernate.mapping.BasicValue;
|
import org.hibernate.mapping.BasicValue;
|
||||||
|
@ -176,6 +177,7 @@ public class JavaTimeJdbcTypeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle drivers truncate fractional seconds from the LocalTime", matchSubTypes = true)
|
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle drivers truncate fractional seconds from the LocalTime", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA time type does not support fractional seconds", matchSubTypes = true)
|
||||||
void testLocalTime(SessionFactoryScope scope) {
|
void testLocalTime(SessionFactoryScope scope) {
|
||||||
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||||
final LocalTime startTime = roundToDefaultPrecision( LocalTime.now(), dialect );
|
final LocalTime startTime = roundToDefaultPrecision( LocalTime.now(), dialect );
|
||||||
|
|
|
@ -15,14 +15,12 @@ import java.time.ZonedDateTime;
|
||||||
|
|
||||||
import org.hibernate.annotations.FractionalSeconds;
|
import org.hibernate.annotations.FractionalSeconds;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
import org.hibernate.dialect.CockroachDialect;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.HANADialect;
|
||||||
import org.hibernate.dialect.HSQLDialect;
|
|
||||||
import org.hibernate.dialect.MariaDBDialect;
|
import org.hibernate.dialect.MariaDBDialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQLDialect;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
import org.hibernate.dialect.SybaseDialect;
|
import org.hibernate.dialect.SybaseDialect;
|
||||||
|
@ -97,7 +95,6 @@ public class FractionalSecondsTests {
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity.class)
|
@DomainModel(annotatedClasses = TestEntity.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = DB2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage(SessionFactoryScope scope) {
|
void testUsage(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -111,28 +108,16 @@ public class FractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity testEntity = session.find( TestEntity.class, 1 );
|
final TestEntity testEntity = session.find( TestEntity.class, 1 );
|
||||||
|
|
||||||
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
if ( dialect instanceof DerbyDialect
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToDefaultPrecision( start, dialect ) );
|
||||||
|| dialect instanceof MariaDBDialect ) {
|
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( start );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 6 ) );
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity0.class)
|
@DomainModel(annotatedClasses = TestEntity0.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = H2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = MariaDBDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = MySQLDialect.class, reason = "Occasional mismatch in rounding versus our code", matchSubTypes = true )
|
|
||||||
@SkipForDialect( dialectClass = OracleDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = SQLServerDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = PostgreSQLDialect.class, reason = "Occasional mismatch in rounding versus our code", matchSubTypes = true )
|
|
||||||
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage0(SessionFactoryScope scope) {
|
void testUsage0(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -146,17 +131,16 @@ public class FractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity0 testEntity = session.find( TestEntity0.class, 1 );
|
final TestEntity0 testEntity = session.find( TestEntity0.class, 1 );
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 0 ) );
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToPrecision( start, 0, dialect ) );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity3.class)
|
@DomainModel(annotatedClasses = TestEntity3.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = MariaDBDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = HSQLDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = DB2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage3(SessionFactoryScope scope) {
|
void testUsage3(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -170,7 +154,8 @@ public class FractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity3 testEntity = session.find( TestEntity3.class, 1 );
|
final TestEntity3 testEntity = session.find( TestEntity3.class, 1 );
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 3 ) );
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToPrecision( start, 3, dialect ) );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +166,9 @@ public class FractionalSecondsTests {
|
||||||
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL only supports precision <= 6", matchSubTypes = true)
|
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL only supports precision <= 6", matchSubTypes = true)
|
||||||
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server only supports precision <= 6")
|
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server only supports precision <= 6")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = PostgreSQLDialect.class, reason = "PostgreSQL only supports precision <= 6", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = CockroachDialect.class, reason = "CockroachDB only supports precision <= 6")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
void testUsage9(SessionFactoryScope scope) {
|
void testUsage9(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,12 @@ import java.time.ZonedDateTime;
|
||||||
import org.hibernate.annotations.FractionalSeconds;
|
import org.hibernate.annotations.FractionalSeconds;
|
||||||
import org.hibernate.annotations.JdbcTypeCode;
|
import org.hibernate.annotations.JdbcTypeCode;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
import org.hibernate.dialect.CockroachDialect;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.HANADialect;
|
||||||
import org.hibernate.dialect.HSQLDialect;
|
|
||||||
import org.hibernate.dialect.MariaDBDialect;
|
import org.hibernate.dialect.MariaDBDialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQLDialect;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
import org.hibernate.dialect.SybaseDialect;
|
import org.hibernate.dialect.SybaseDialect;
|
||||||
|
@ -99,7 +97,6 @@ public class JavaTimeFractionalSecondsTests {
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity.class)
|
@DomainModel(annotatedClasses = TestEntity.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = DB2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage(SessionFactoryScope scope) {
|
void testUsage(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -113,28 +110,16 @@ public class JavaTimeFractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity testEntity = session.find( TestEntity.class, 1 );
|
final TestEntity testEntity = session.find( TestEntity.class, 1 );
|
||||||
|
|
||||||
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
if ( dialect instanceof DerbyDialect
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToDefaultPrecision( start, dialect ) );
|
||||||
|| dialect instanceof MariaDBDialect ) {
|
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( start );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 6 ) );
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity0.class)
|
@DomainModel(annotatedClasses = TestEntity0.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = H2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = MariaDBDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = MySQLDialect.class, reason = "Occasional mismatch in rounding versus our code", matchSubTypes = true )
|
|
||||||
@SkipForDialect( dialectClass = OracleDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = SQLServerDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = PostgreSQLDialect.class, reason = "Occasional mismatch in rounding versus our code", matchSubTypes = true )
|
|
||||||
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage0(SessionFactoryScope scope) {
|
void testUsage0(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -148,17 +133,16 @@ public class JavaTimeFractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity0 testEntity = session.find( TestEntity0.class, 1 );
|
final TestEntity0 testEntity = session.find( TestEntity0.class, 1 );
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 0 ) );
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToPrecision( start, 0, dialect ) );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DomainModel(annotatedClasses = TestEntity3.class)
|
@DomainModel(annotatedClasses = TestEntity3.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@SkipForDialect( dialectClass = MariaDBDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = HSQLDialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect( dialectClass = DB2Dialect.class, reason = "Occasional mismatch in rounding versus our code" )
|
|
||||||
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby does not support sized timestamp")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
void testUsage3(SessionFactoryScope scope) {
|
void testUsage3(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
@ -172,7 +156,8 @@ public class JavaTimeFractionalSecondsTests {
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
scope.inTransaction( (session) -> {
|
||||||
final TestEntity3 testEntity = session.find( TestEntity3.class, 1 );
|
final TestEntity3 testEntity = session.find( TestEntity3.class, 1 );
|
||||||
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.roundToSecondPrecision( start, 3 ) );
|
final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
assertThat( testEntity.theInstant ).isEqualTo( DateTimeUtils.adjustToPrecision( start, 3, dialect ) );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +168,9 @@ public class JavaTimeFractionalSecondsTests {
|
||||||
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL only supports precision <= 6", matchSubTypes = true)
|
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL only supports precision <= 6", matchSubTypes = true)
|
||||||
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server only supports precision <= 6")
|
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server only supports precision <= 6")
|
||||||
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
@SkipForDialect(dialectClass = SybaseDialect.class, reason = "Because... Sybase...", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = PostgreSQLDialect.class, reason = "PostgreSQL only supports precision <= 6", matchSubTypes = true)
|
||||||
|
@SkipForDialect(dialectClass = CockroachDialect.class, reason = "CockroachDB only supports precision <= 6")
|
||||||
|
@SkipForDialect(dialectClass = HANADialect.class, reason = "HANA does not support specifying a precision on timestamps")
|
||||||
void testUsage9(SessionFactoryScope scope) {
|
void testUsage9(SessionFactoryScope scope) {
|
||||||
final Instant start = Instant.now();
|
final Instant start = Instant.now();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue