HHH-15135 Respect precision in temporal version types when generating timestamps

This commit is contained in:
Christian Beikov 2022-03-21 19:06:41 +01:00
parent 8470d6db5b
commit 75a8ad1851
27 changed files with 288 additions and 147 deletions

View File

@ -80,6 +80,9 @@ public class UnsavedValueFactory {
public static <T> VersionValue getUnsavedVersionValue( public static <T> VersionValue getUnsavedVersionValue(
KeyValue bootVersionMapping, KeyValue bootVersionMapping,
VersionJavaType<T> jtd, VersionJavaType<T> jtd,
Long length,
Integer precision,
Integer scale,
Getter getter, Getter getter,
Supplier<?> templateInstanceAccess) { Supplier<?> templateInstanceAccess) {
final String unsavedValue = bootVersionMapping.getNullValue(); final String unsavedValue = bootVersionMapping.getNullValue();
@ -91,7 +94,7 @@ public class UnsavedValueFactory {
// if the version of a newly instantiated object is not the same // if the version of a newly instantiated object is not the same
// as the version seed value, use that as the unsaved-value // as the version seed value, use that as the unsaved-value
final T seedValue = jtd.seed( null ); final T seedValue = jtd.seed( length, precision, scale, null );
return jtd.areEqual( seedValue, defaultValue ) return jtd.areEqual( seedValue, defaultValue )
? VersionValue.UNDEFINED ? VersionValue.UNDEFINED
: new VersionValue( defaultValue ); : new VersionValue( defaultValue );
@ -116,72 +119,6 @@ public class UnsavedValueFactory {
} }
/**
* Instantiate a class using the provided Constructor
*
* @param constructor The constructor
*
* @return The instantiated object
*
* @throws InstantiationException if something went wrong
*/
private static Object instantiate(Constructor<?> constructor) {
try {
return constructor.newInstance();
}
catch (Exception e) {
throw new InstantiationException( "could not instantiate test object", constructor.getDeclaringClass(), e );
}
}
/**
* Return an IdentifierValue for the specified unsaved-value. If none is specified,
* guess the unsaved value by instantiating a test instance of the class and
* reading it's version property value, or if that is not possible, using the java default
* value for the type
*
* @param versionUnsavedValue The mapping defined unsaved value
* @param versionGetter The version attribute getter
* @param versionType The mapping type for the version
* @param constructor The constructor for the entity
*
* @return The appropriate VersionValue
*/
public static <X> VersionValue getUnsavedVersionValue(
String versionUnsavedValue,
Getter versionGetter,
VersionJavaType<X> versionType,
Constructor<?> constructor) {
if ( versionUnsavedValue == null ) {
if ( constructor!=null ) {
@SuppressWarnings("unchecked")
final X defaultValue = (X) versionGetter.get( instantiate( constructor ) );
// if the version of a newly instantiated object is not the same
// as the version seed value, use that as the unsaved-value
return versionType.areEqual( versionType.seed( null ), defaultValue )
? VersionValue.UNDEFINED
: new VersionValue( defaultValue );
}
else {
return VersionValue.UNDEFINED;
}
}
else {
switch (versionUnsavedValue) {
case "undefined":
return VersionValue.UNDEFINED;
case "null":
return VersionValue.NULL;
case "negative":
return VersionValue.NEGATIVE;
default:
// this should not happen since the DTD prevents it
throw new MappingException("Could not parse version unsaved-value: " + versionUnsavedValue);
}
}
}
private UnsavedValueFactory() { private UnsavedValueFactory() {
} }
} }

View File

@ -8,6 +8,7 @@ package org.hibernate.engine.internal;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.descriptor.java.VersionJavaType; import org.hibernate.type.descriptor.java.VersionJavaType;
@ -31,15 +32,20 @@ public final class Versioning {
} }
/** /**
* Create an initial optimistic locking value according the {@link VersionJavaType} * Create an initial optimistic locking value according the {@link EntityVersionMapping}
* contract for the version property. * contract for the version property.
* *
* @param versionType The version type. * @param versionMapping The version mapping
* @param session The originating session * @param session The originating session
* @return The initial optimistic locking value * @return The initial optimistic locking value
*/ */
private static Object seed(VersionJavaType<Object> versionType, SharedSessionContractImplementor session) { private static Object seed(EntityVersionMapping versionMapping, SharedSessionContractImplementor session) {
final Object seed = versionType.seed( session ); final Object seed = versionMapping.getJavaType().seed(
versionMapping.getLength(),
versionMapping.getPrecision(),
versionMapping.getScale(),
session
);
LOG.tracef( "Seeding: %s", seed ); LOG.tracef( "Seeding: %s", seed );
return seed; return seed;
} }
@ -51,7 +57,7 @@ public final class Versioning {
* *
* @param fields The current snapshot state * @param fields The current snapshot state
* @param versionProperty The index of the version property * @param versionProperty The index of the version property
* @param versionType The version type * @param versionMapping The version mapping
* @param session The originating session * @param session The originating session
* @return True if we injected a new version value into the fields array; false * @return True if we injected a new version value into the fields array; false
* otherwise. * otherwise.
@ -59,7 +65,7 @@ public final class Versioning {
public static boolean seedVersion( public static boolean seedVersion(
Object[] fields, Object[] fields,
int versionProperty, int versionProperty,
VersionJavaType<Object> versionType, EntityVersionMapping versionMapping,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
final Object initialVersion = fields[versionProperty]; final Object initialVersion = fields[versionProperty];
if ( if (
@ -70,7 +76,7 @@ public final class Versioning {
// TODO: shift it into unsaved-value strategy // TODO: shift it into unsaved-value strategy
( (initialVersion instanceof Number) && ( (Number) initialVersion ).longValue()<0 ) ( (initialVersion instanceof Number) && ( (Number) initialVersion ).longValue()<0 )
) { ) {
fields[versionProperty] = seed( versionType, session ); fields[versionProperty] = seed( versionMapping, session );
return true; return true;
} }
LOG.tracev( "Using initial version: {0}", initialVersion ); LOG.tracev( "Using initial version: {0}", initialVersion );
@ -83,12 +89,20 @@ public final class Versioning {
* the {@link VersionJavaType} contract for the version property. * the {@link VersionJavaType} contract for the version property.
* *
* @param version The current version * @param version The current version
* @param versionType The version type * @param versionMapping The version mapping
* @param session The originating session * @param session The originating session
* @return The incremented optimistic locking value. * @return The incremented optimistic locking value.
*/ */
public static Object increment(Object version, VersionJavaType<Object> versionType, SharedSessionContractImplementor session) { public static Object increment(Object version, EntityVersionMapping versionMapping, SharedSessionContractImplementor session) {
final Object next = versionType.next( version, session ); @SuppressWarnings("unchecked")
final VersionJavaType<Object> versionType = (VersionJavaType<Object>) versionMapping.getJavaType();
final Object next = versionType.next(
version,
versionMapping.getLength(),
versionMapping.getPrecision(),
versionMapping.getScale(),
session
);
if ( LOG.isTraceEnabled() ) { if ( LOG.isTraceEnabled() ) {
LOG.tracef( LOG.tracef(
"Incrementing: %s to %s", "Incrementing: %s to %s",

View File

@ -414,7 +414,7 @@ public abstract class AbstractSaveEventListener<C>
substitute = Versioning.seedVersion( substitute = Versioning.seedVersion(
values, values,
persister.getVersionProperty(), persister.getVersionProperty(),
persister.getVersionJavaType(), persister.getVersionMapping(),
source source
) || substitute; ) || substitute;
} }

View File

@ -397,7 +397,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
); );
final Object nextVersion = isVersionIncrementRequired final Object nextVersion = isVersionIncrementRequired
? Versioning.increment( entry.getVersion(), persister.getVersionJavaType(), event.getSession() ) ? Versioning.increment( entry.getVersion(), persister.getVersionMapping(), event.getSession() )
: entry.getVersion(); //use the current version : entry.getVersion(); //use the current version
Versioning.setVersion( values, nextVersion, persister ); Versioning.setVersion( values, nextVersion, persister );

View File

@ -88,7 +88,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
boolean substitute = Versioning.seedVersion( boolean substitute = Versioning.seedVersion(
state, state,
persister.getVersionProperty(), persister.getVersionProperty(),
persister.getVersionJavaType(), persister.getVersionMapping(),
this this
); );
if ( substitute ) { if ( substitute ) {
@ -141,7 +141,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
Object oldVersion; Object oldVersion;
if ( persister.isVersioned() ) { if ( persister.isVersioned() ) {
oldVersion = persister.getVersion( entity ); oldVersion = persister.getVersion( entity );
Object newVersion = Versioning.increment( oldVersion, persister.getVersionJavaType(), this ); Object newVersion = Versioning.increment( oldVersion, persister.getVersionMapping(), this );
Versioning.setVersion( state, newVersion, persister ); Versioning.setVersion( state, newVersion, persister );
persister.setValues( entity, state ); persister.setValues( entity, state );
} }

View File

@ -8,6 +8,8 @@ package org.hibernate.metamodel.mapping;
import org.hibernate.engine.spi.VersionValue; import org.hibernate.engine.spi.VersionValue;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.VersionJavaType;
/** /**
* Describes the mapping of an entity's version * Describes the mapping of an entity's version
@ -25,4 +27,12 @@ public interface EntityVersionMapping extends BasicValuedModelPart {
* state based on the version mapping * state based on the version mapping
*/ */
VersionValue getUnsavedStrategy(); VersionValue getUnsavedStrategy();
@Override
VersionJavaType<?> getJavaType();
@Override
default VersionJavaType<?> getExpressibleJavaType() {
return (VersionJavaType<?>) getMappedType().getMappedJavaType();
}
} }

View File

@ -89,6 +89,9 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
unsavedValueStrategy = UnsavedValueFactory.getUnsavedVersionValue( unsavedValueStrategy = UnsavedValueFactory.getUnsavedVersionValue(
(KeyValue) bootEntityDescriptor.getVersion().getValue(), (KeyValue) bootEntityDescriptor.getVersion().getValue(),
(VersionJavaType<?>) versionBasicType.getJavaTypeDescriptor(), (VersionJavaType<?>) versionBasicType.getJavaTypeDescriptor(),
length,
precision,
scale,
declaringType declaringType
.getRepresentationStrategy() .getRepresentationStrategy()
.resolvePropertyAccess( bootEntityDescriptor.getVersion() ) .resolvePropertyAccess( bootEntityDescriptor.getVersion() )
@ -168,8 +171,8 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
} }
@Override @Override
public JavaType<?> getJavaType() { public VersionJavaType<?> getJavaType() {
return versionBasicType.getJavaTypeDescriptor(); return (VersionJavaType<?>) versionBasicType.getJavaTypeDescriptor();
} }
@Override @Override

View File

@ -2093,9 +2093,16 @@ public abstract class AbstractEntityPersister
// the difficulty here is exactly what we update in order to // the difficulty here is exactly what we update in order to
// force the version to be incremented in the db... // force the version to be incremented in the db...
throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" ); throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" );
}
Object nextVersion = getVersionJavaType().next( currentVersion, session ); }
final EntityVersionMapping versionMapping = getVersionMapping();
final Object nextVersion = getVersionJavaType().next(
currentVersion,
versionMapping.getLength(),
versionMapping.getPrecision(),
versionMapping.getScale(),
session
);
if ( LOG.isTraceEnabled() ) { if ( LOG.isTraceEnabled() ) {
LOG.trace( LOG.trace(
"Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + "; " "Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + "; "

View File

@ -806,7 +806,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
final ColumnReference versionColumn = targetColumnReferences.get( 0 ); final ColumnReference versionColumn = targetColumnReferences.get( 0 );
final Expression value; final Expression value;
if ( versionMapping.getJdbcMapping().getJdbcType().isTemporal() ) { if ( versionMapping.getJdbcMapping().getJdbcType().isTemporal() ) {
value = new VersionTypeSeedParameterSpecification( versionType, persister.getVersionJavaType() ); value = new VersionTypeSeedParameterSpecification( versionMapping );
} }
else { else {
value = new BinaryArithmeticExpression( value = new BinaryArithmeticExpression(
@ -1201,10 +1201,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
assert targetColumnReferences.size() == 1; assert targetColumnReferences.size() == 1;
targetColumnReferenceConsumer.accept( versionPath, targetColumnReferences ); targetColumnReferenceConsumer.accept( versionPath, targetColumnReferences );
versionExpression = new VersionTypeSeedParameterSpecification( versionExpression = new VersionTypeSeedParameterSpecification( entityDescriptor.getVersionMapping() );
entityDescriptor.getVersionMapping().getJdbcMapping(),
entityDescriptor.getVersionJavaType()
);
} }
if ( discriminatorMapping != null && discriminatorMapping.isPhysical() ) { if ( discriminatorMapping != null && discriminatorMapping.isPhysical() ) {
final BasicValuedPathInterpretation<?> discriminatorPath = new BasicValuedPathInterpretation<>( final BasicValuedPathInterpretation<?> discriminatorPath = new BasicValuedPathInterpretation<>(

View File

@ -9,6 +9,7 @@ package org.hibernate.sql.exec.internal;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -20,16 +21,16 @@ import org.hibernate.type.descriptor.java.VersionJavaType;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class VersionTypeSeedParameterSpecification extends AbstractJdbcParameter { public class VersionTypeSeedParameterSpecification extends AbstractJdbcParameter {
private final VersionJavaType<?> type; private final EntityVersionMapping versionMapping;
/** /**
* Constructs a version seed parameter bind specification. * Constructs a version seed parameter bind specification.
* *
* @param type The version type. * @param versionMapping The version mapping.
*/ */
public VersionTypeSeedParameterSpecification(JdbcMapping jdbcMapping, VersionJavaType<?> type) { public VersionTypeSeedParameterSpecification(EntityVersionMapping versionMapping) {
super( jdbcMapping ); super( versionMapping.getJdbcMapping() );
this.type = type; this.versionMapping = versionMapping;
} }
@Override @Override
@ -41,7 +42,12 @@ public class VersionTypeSeedParameterSpecification extends AbstractJdbcParameter
//noinspection unchecked //noinspection unchecked
getJdbcMapping().getJdbcValueBinder().bind( getJdbcMapping().getJdbcValueBinder().bind(
statement, statement,
type.seed( executionContext.getSession() ), versionMapping.getJavaType().seed(
versionMapping.getLength(),
versionMapping.getPrecision(),
versionMapping.getScale(),
executionContext.getSession()
),
startPosition, startPosition,
executionContext.getSession() executionContext.getSession()
); );

View File

@ -176,12 +176,19 @@ public class ByteJavaType extends AbstractClassJavaType<Byte>
); );
} }
@Override @Override
public Byte next(Byte current, SharedSessionContractImplementor session) { public Byte next(
Byte current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return (byte) ( current + 1 ); return (byte) ( current + 1 );
} }
@Override @Override
public Byte seed(SharedSessionContractImplementor session) { public Byte seed(
Long length,
Integer precision, Integer scale, SharedSessionContractImplementor session) {
return ZERO; return ZERO;
} }
} }

View File

@ -6,7 +6,9 @@
*/ */
package org.hibernate.type.descriptor.java; package org.hibernate.type.descriptor.java;
import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.time.ZonedDateTime;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -155,12 +157,17 @@ public class CalendarJavaType extends AbstractTemporalJavaType<Calendar> impleme
} }
@Override @Override
public Calendar next(Calendar current, SharedSessionContractImplementor session) { public Calendar next(
return seed( session ); Calendar current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return seed( length, precision, scale, session );
} }
@Override @Override
public Calendar seed(SharedSessionContractImplementor session) { public Calendar seed(Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
return Calendar.getInstance(); return GregorianCalendar.from( ZonedDateTime.now( ClockHelper.forPrecision( precision, session ) ) );
} }
} }

View File

@ -0,0 +1,62 @@
/*
* 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.type.descriptor.java;
import java.time.Clock;
import java.time.Duration;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Helper for determining the correct clock for precision
*/
public class ClockHelper {
private static final Duration TICK_8 = Duration.ofNanos( 10L );
private static final Duration TICK_7 = Duration.ofNanos( 100L );
private static final Duration TICK_6 = Duration.ofNanos( 1000L );
private static final Duration TICK_5 = Duration.ofNanos( 10000L );
private static final Duration TICK_4 = Duration.ofNanos( 100000L );
private static final Duration TICK_3 = Duration.ofNanos( 1000000L );
private static final Duration TICK_2 = Duration.ofNanos( 10000000L );
private static final Duration TICK_1 = Duration.ofNanos( 100000000L );
private static final Duration TICK_0 = Duration.ofNanos( 1000000000L );
public static Clock forPrecision(Integer precision, SharedSessionContractImplementor session) {
final int resolvedPrecision;
if ( precision == null ) {
resolvedPrecision = session.getJdbcServices().getDialect().getDefaultTimestampPrecision();
}
else {
resolvedPrecision = precision;
}
final Clock clock = Clock.systemDefaultZone();
switch ( resolvedPrecision ) {
case 0:
return Clock.tick( clock, TICK_0 );
case 1:
return Clock.tick( clock, TICK_1 );
case 2:
return Clock.tick( clock, TICK_2 );
case 3:
return Clock.tick( clock, TICK_3 );
case 4:
return Clock.tick( clock, TICK_4 );
case 5:
return Clock.tick( clock, TICK_5 );
case 6:
return Clock.tick( clock, TICK_6 );
case 7:
return Clock.tick( clock, TICK_7 );
case 8:
return Clock.tick( clock, TICK_8 );
case 9:
return clock;
}
throw new IllegalArgumentException( "Illegal precision: " + resolvedPrecision );
}
}

View File

@ -166,12 +166,19 @@ public class DateJavaType extends AbstractTemporalJavaType<Date> implements Vers
} }
@Override @Override
public Date next(Date current, SharedSessionContractImplementor session) { public Date next(
return seed( session ); Date current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return seed( length, precision, scale, session );
} }
@Override @Override
public Date seed(SharedSessionContractImplementor session) { public Date seed(
return new Timestamp( System.currentTimeMillis() ); Long length,
Integer precision, Integer scale, SharedSessionContractImplementor session) {
return Timestamp.from( ClockHelper.forPrecision( precision, session ).instant() );
} }
} }

View File

@ -47,20 +47,29 @@ public class DbTimestampJavaType<T> implements VersionJavaType<T>, TemporalJavaT
} }
@Override @Override
public T next(T current, SharedSessionContractImplementor session) { public T next(
return seed( session ); T current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return seed( length, precision, scale, session );
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T seed(SharedSessionContractImplementor session) { public T seed(
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
if ( session == null ) { if ( session == null ) {
LOG.trace( "Incoming session was null; using current jvm time" ); LOG.trace( "Incoming session was null; using current jvm time" );
return ((VersionJavaType<T>) delegate).seed( null ); return ((VersionJavaType<T>) delegate).seed( length, precision, scale, null );
} }
else if ( !session.getJdbcServices().getJdbcEnvironment().getDialect().supportsCurrentTimestampSelection() ) { else if ( !session.getJdbcServices().getJdbcEnvironment().getDialect().supportsCurrentTimestampSelection() ) {
LOG.debug( "Falling back to vm-based timestamp, as dialect does not support current timestamp selection" ); LOG.debug( "Falling back to vm-based timestamp, as dialect does not support current timestamp selection" );
return ((VersionJavaType<T>) delegate).seed( session ); return ((VersionJavaType<T>) delegate).seed( length, precision, scale, session );
} }
else { else {
return getCurrentTimestamp( session ); return getCurrentTimestamp( session );

View File

@ -7,7 +7,6 @@
package org.hibernate.type.descriptor.java; package org.hibernate.type.descriptor.java;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant; import java.time.Instant;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@ -196,13 +195,18 @@ public class InstantJavaType extends AbstractTemporalJavaType<Instant>
} }
@Override @Override
public Instant seed(SharedSessionContractImplementor session) { public Instant seed(Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
return Instant.now(); return Instant.now( ClockHelper.forPrecision( precision, session ) );
} }
@Override @Override
public Instant next(Instant current, SharedSessionContractImplementor session) { public Instant next(
return Instant.now(); Instant current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return Instant.now( ClockHelper.forPrecision( precision, session ) );
} }
} }

View File

@ -195,12 +195,17 @@ public class IntegerJavaType extends AbstractClassJavaType<Integer>
} }
@Override @Override
public Integer seed(SharedSessionContractImplementor session) { public Integer seed(
Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
return ZERO; return ZERO;
} }
@Override @Override
public Integer next(Integer current, SharedSessionContractImplementor session) { public Integer next(
Integer current,
Long length,
Integer precision,
Integer scale, SharedSessionContractImplementor session) {
return current + 1; return current + 1;
} }

View File

@ -216,13 +216,22 @@ public class JdbcTimestampJavaType extends AbstractTemporalJavaType<Date> implem
} }
@Override @Override
public Date next(Date current, SharedSessionContractImplementor session) { public Date next(
return seed( session ); Date current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return seed( length, precision, scale, session );
} }
@Override @Override
public Date seed(SharedSessionContractImplementor session) { public Date seed(
return new Timestamp( System.currentTimeMillis() ); Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return Timestamp.from( ClockHelper.forPrecision( precision, session ).instant() );
} }

View File

@ -163,12 +163,17 @@ public class LocalDateTimeJavaType extends AbstractTemporalJavaType<LocalDateTim
} }
@Override @Override
public LocalDateTime seed(SharedSessionContractImplementor session) { public LocalDateTime seed(Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
return LocalDateTime.now(); return LocalDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
@Override @Override
public LocalDateTime next(LocalDateTime current, SharedSessionContractImplementor session) { public LocalDateTime next(
return LocalDateTime.now(); LocalDateTime current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return LocalDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
} }

View File

@ -197,12 +197,19 @@ public class LongJavaType extends AbstractClassJavaType<Long>
} }
@Override @Override
public Long next(Long current, SharedSessionContractImplementor session) { public Long next(
Long current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return current + 1L; return current + 1L;
} }
@Override @Override
public Long seed(SharedSessionContractImplementor session) { public Long seed(
Long length,
Integer precision, Integer scale, SharedSessionContractImplementor session) {
return ZERO; return ZERO;
} }
} }

View File

@ -206,12 +206,21 @@ public class OffsetDateTimeJavaType extends AbstractTemporalJavaType<OffsetDateT
} }
@Override @Override
public OffsetDateTime seed(SharedSessionContractImplementor session) { public OffsetDateTime seed(
return OffsetDateTime.now(); Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return OffsetDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
@Override @Override
public OffsetDateTime next(OffsetDateTime current, SharedSessionContractImplementor session) { public OffsetDateTime next(
return OffsetDateTime.now(); OffsetDateTime current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return OffsetDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
} }

View File

@ -130,7 +130,8 @@ public class PrimitiveByteArrayJavaType extends AbstractClassJavaType<byte[]>
} }
@Override @Override
public byte[] seed(SharedSessionContractImplementor session) { public byte[] seed(
Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known // Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the // application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which // TIMESTAMP datatype supported by Sybase and SQL Server, which
@ -139,7 +140,11 @@ public class PrimitiveByteArrayJavaType extends AbstractClassJavaType<byte[]>
} }
@Override @Override
public byte[] next(byte[] current, SharedSessionContractImplementor session) { public byte[] next(
byte[] current,
Long length,
Integer precision,
Integer scale, SharedSessionContractImplementor session) {
return current; return current;
} }
} }

View File

@ -125,7 +125,8 @@ public class RowVersionJavaType extends AbstractClassJavaType<byte[]>
} }
@Override @Override
public byte[] seed(SharedSessionContractImplementor session) { public byte[] seed(
Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known // Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the // application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which // TIMESTAMP datatype supported by Sybase and SQL Server, which
@ -134,7 +135,11 @@ public class RowVersionJavaType extends AbstractClassJavaType<byte[]>
} }
@Override @Override
public byte[] next(byte[] current, SharedSessionContractImplementor session) { public byte[] next(
byte[] current,
Long length,
Integer precision,
Integer scale, SharedSessionContractImplementor session) {
return current; return current;
} }
} }

View File

@ -184,12 +184,19 @@ public class ShortJavaType extends AbstractClassJavaType<Short>
); );
} }
@Override @Override
public Short seed(SharedSessionContractImplementor session) { public Short seed(
Long length,
Integer precision, Integer scale, SharedSessionContractImplementor session) {
return ZERO; return ZERO;
} }
@Override @Override
public Short next(Short current, SharedSessionContractImplementor session) { public Short next(
Short current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return (short) ( current + 1 ); return (short) ( current + 1 );
} }
} }

View File

@ -17,18 +17,24 @@ public interface VersionJavaType<T> extends JavaType<T> {
/** /**
* Generate an initial version. * Generate an initial version.
* *
* @param length The length of the type
* @param precision The precision of the type
* @param scale The scale of the type
* @param session The session from which this request originates. * @param session The session from which this request originates.
* @return an instance of the type * @return an instance of the type
*/ */
T seed(SharedSessionContractImplementor session); T seed(Long length, Integer precision, Integer scale, SharedSessionContractImplementor session);
/** /**
* Increment the version. * Increment the version.
* *
* @param session The session from which this request originates.
* @param current the current version * @param current the current version
* @param length The length of the type
* @param precision The precision of the type
* @param scale The scale of the type
* @param session The session from which this request originates.
* @return an instance of the type * @return an instance of the type
*/ */
T next(T current, SharedSessionContractImplementor session); T next(T current, Long length, Integer precision, Integer scale, SharedSessionContractImplementor session);
} }

View File

@ -206,12 +206,17 @@ public class ZonedDateTimeJavaType extends AbstractTemporalJavaType<ZonedDateTim
} }
@Override @Override
public ZonedDateTime seed(SharedSessionContractImplementor session) { public ZonedDateTime seed(Long length, Integer precision, Integer scale, SharedSessionContractImplementor session) {
return ZonedDateTime.now(); return ZonedDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
@Override @Override
public ZonedDateTime next(ZonedDateTime current, SharedSessionContractImplementor session) { public ZonedDateTime next(
return ZonedDateTime.now(); ZonedDateTime current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return ZonedDateTime.now( ClockHelper.forPrecision( precision, session ) );
} }
} }

View File

@ -21,12 +21,20 @@ public class UserTypeVersionJavaTypeWrapper<J> extends UserTypeJavaTypeWrapper<J
} }
@Override @Override
public J seed(SharedSessionContractImplementor session) { public J seed(
Long length,
Integer precision,
Integer scale, SharedSessionContractImplementor session) {
return ( (UserVersionType<J>) userType ).seed( session ); return ( (UserVersionType<J>) userType ).seed( session );
} }
@Override @Override
public J next(J current, SharedSessionContractImplementor session) { public J next(
J current,
Long length,
Integer precision,
Integer scale,
SharedSessionContractImplementor session) {
return ( (UserVersionType<J>) userType ).next( current, session ); return ( (UserVersionType<J>) userType ).next( current, session );
} }
} }