Move VersionType logic to VersionJavaTypeDescriptor

This commit is contained in:
Christian Beikov 2021-10-05 15:39:56 +02:00
parent 81e66fa970
commit 653f62ac60
57 changed files with 625 additions and 530 deletions

View File

@ -6,14 +6,10 @@
*/
package org.hibernate.userguide.collections.type;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BigIntTypeDescriptor;
@ -22,9 +18,7 @@ import org.hibernate.type.descriptor.jdbc.BigIntTypeDescriptor;
*/
//tag::collections-map-custom-key-type-mapping-example[]
public class TimestampEpochType
extends AbstractSingleColumnStandardBasicType<Date>
implements VersionType<Date> {
public class TimestampEpochType extends AbstractSingleColumnStandardBasicType<Date> {
public static final TimestampEpochType INSTANCE = new TimestampEpochType();
@ -41,26 +35,7 @@ public class TimestampEpochType
}
@Override
public Date next(
Date current,
SharedSessionContractImplementor session) {
return seed( session );
}
@Override
public Date seed(
SharedSessionContractImplementor session) {
return new Timestamp( System.currentTimeMillis() );
}
@Override
public Comparator<Date> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
@Override
public Date fromStringValue(
CharSequence xml) throws HibernateException {
public Date fromStringValue(CharSequence xml) throws HibernateException {
return fromString( xml );
}
}

View File

@ -6,7 +6,7 @@
*/
package org.hibernate;
import org.hibernate.type.VersionType;
import org.hibernate.type.BasicType;
/**
* Represents a replication strategy.
@ -20,7 +20,7 @@ public enum ReplicationMode {
*/
EXCEPTION {
@Override
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, BasicType<Object> versionType) {
throw new AssertionFailure( "should not be called" );
}
},
@ -29,7 +29,7 @@ public enum ReplicationMode {
*/
IGNORE {
@Override
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, BasicType<Object> versionType) {
return false;
}
},
@ -38,7 +38,7 @@ public enum ReplicationMode {
*/
OVERWRITE {
@Override
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, BasicType<Object> versionType) {
return true;
}
},
@ -48,9 +48,9 @@ public enum ReplicationMode {
LATEST_VERSION {
@Override
@SuppressWarnings("unchecked")
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, BasicType<Object> versionType) {
// always overwrite non-versioned data (because we don't know which is newer)
return versionType == null || versionType.getComparator().compare( currentVersion, newVersion ) <= 0;
return versionType == null || versionType.getJavaTypeDescriptor().getComparator().compare( currentVersion, newVersion ) <= 0;
}
};
@ -64,6 +64,6 @@ public enum ReplicationMode {
*
* @return {@code true} indicates the data should be overwritten; {@code false} indicates it should not.
*/
public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType);
public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, BasicType<Object> versionType);
}

View File

@ -29,7 +29,7 @@ public enum SourceType {
}
/**
* Get the corresponding Hibernate {@link org.hibernate.type.VersionType} name.
* Get the corresponding Hibernate {@link org.hibernate.type.BasicType} name.
*
* @return The corresponding type name.
*/

View File

@ -12,7 +12,7 @@ import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.mapping.Collection;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.type.VersionType;
import org.hibernate.type.BasicType;
/**
* @author Steve Ebersole
@ -46,7 +46,7 @@ public class CollectionDataCachingConfigImpl
if ( !isVersioned() ) {
return null;
}
return ( (VersionType) collectionDescriptor.getOwner().getVersion().getType() ).getComparator();
return ( (BasicType<?>) collectionDescriptor.getOwner().getVersion().getType() ).getJavaTypeDescriptor().getComparator();
}
@Override

View File

@ -24,7 +24,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.type.VersionType;
import org.hibernate.type.BasicType;
/**
* DomainDataRegionConfig implementation
@ -99,7 +99,7 @@ public class DomainDataRegionConfigImpl implements DomainDataRegionConfig {
x -> new EntityDataCachingConfigImpl(
rootEntityName,
bootEntityDescriptor.isVersioned()
? (Supplier<Comparator>) () -> ( (VersionType) bootEntityDescriptor.getVersion().getType() ).getComparator()
? (Supplier<Comparator>) () -> ( (BasicType<?>) bootEntityDescriptor.getVersion().getType() ).getJavaTypeDescriptor().getComparator()
: null,
bootEntityDescriptor.isMutable(),
accessType

View File

@ -21,8 +21,8 @@ import org.hibernate.persister.entity.Lockable;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.sql.Update;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.jboss.logging.Logger;
@ -84,7 +84,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
final JdbcCoordinator jdbcCoordinator = session.getJdbcCoordinator();
final PreparedStatement st = jdbcCoordinator.getStatementPreparer().prepareStatement( sql );
try {
final VersionType lockableVersionType = lockable.getVersionType();
final BasicType<?> lockableVersionType = lockable.getVersionType();
lockableVersionType.nullSafeSet( st, version, 1, session );
int offset = 2;

View File

@ -17,7 +17,7 @@ import org.hibernate.property.access.spi.Getter;
import org.hibernate.type.IdentifierType;
import org.hibernate.type.PrimitiveType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
/**
* Helper for dealing with unsaved value handling
@ -114,18 +114,19 @@ public class UnsavedValueFactory {
*
* @return The appropriate VersionValue
*/
public static VersionValue getUnsavedVersionValue(
String versionUnsavedValue,
public static <X> VersionValue getUnsavedVersionValue(
String versionUnsavedValue,
Getter versionGetter,
VersionType versionType,
VersionJavaTypeDescriptor<X> versionType,
Constructor constructor) {
if ( versionUnsavedValue == null ) {
if ( constructor!=null ) {
final Object defaultValue = versionGetter.get( instantiate( constructor ) );
@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.isEqual( versionType.seed( null ), defaultValue )
return versionType.areEqual( versionType.seed( null ), defaultValue )
? VersionValue.UNDEFINED
: new VersionValue( defaultValue );
}

View File

@ -9,7 +9,7 @@ package org.hibernate.engine.internal;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
import org.jboss.logging.Logger;
@ -31,21 +31,21 @@ public final class Versioning {
}
/**
* Create an initial optimistic locking value according the {@link VersionType}
* Create an initial optimistic locking value according the {@link VersionJavaTypeDescriptor}
* contract for the version property.
*
* @param versionType The version type.
* @param session The originating session
* @return The initial optimistic locking value
*/
private static Object seed(VersionType versionType, SharedSessionContractImplementor session) {
private static Object seed(VersionJavaTypeDescriptor<Object> versionType, SharedSessionContractImplementor session) {
final Object seed = versionType.seed( session );
LOG.tracef( "Seeding: %s", seed );
return seed;
}
/**
* Create an initial optimistic locking value according the {@link VersionType}
* Create an initial optimistic locking value according the {@link VersionJavaTypeDescriptor}
* contract for the version property <b>if required</b> and inject it into
* the snapshot state.
*
@ -59,7 +59,7 @@ public final class Versioning {
public static boolean seedVersion(
Object[] fields,
int versionProperty,
VersionType versionType,
VersionJavaTypeDescriptor<Object> versionType,
SharedSessionContractImplementor session) {
final Object initialVersion = fields[versionProperty];
if (
@ -80,21 +80,20 @@ public final class Versioning {
/**
* Generate the next increment in the optimistic locking value according
* the {@link VersionType} contract for the version property.
* the {@link VersionJavaTypeDescriptor} contract for the version property.
*
* @param version The current version
* @param versionType The version type
* @param session The originating session
* @return The incremented optimistic locking value.
*/
@SuppressWarnings("unchecked")
public static Object increment(Object version, VersionType versionType, SharedSessionContractImplementor session) {
public static Object increment(Object version, VersionJavaTypeDescriptor<Object> versionType, SharedSessionContractImplementor session) {
final Object next = versionType.next( version, session );
if ( LOG.isTraceEnabled() ) {
LOG.tracef(
"Incrementing: %s to %s",
versionType.toLoggableString( version, session.getFactory() ),
versionType.toLoggableString( next, session.getFactory() )
versionType.toString( version ),
versionType.toString( next )
);
}
return next;

View File

@ -55,6 +55,7 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -444,4 +445,9 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
public AllowableParameterType<?> resolveParameterBindType(Class<?> clazz) {
return delegate.resolveParameterBindType( clazz );
}
@Override
public WrapperOptions getWrapperOptions() {
return delegate.getWrapperOptions();
}
}

View File

@ -410,7 +410,7 @@ public abstract class AbstractSaveEventListener
substitute = Versioning.seedVersion(
values,
persister.getVersionProperty(),
persister.getVersionType(),
persister.getVersionJavaTypeDescriptor(),
source
) || substitute;
}

View File

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

View File

@ -25,6 +25,7 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
/**
@ -96,11 +97,12 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
/// HHH-2378
final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
@SuppressWarnings("unchecked")
boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
entity,
realOldVersion,
persister.getVersion( entity ),
persister.getVersionType()
(BasicType<Object>) persister.getVersionType()
);
// if can replicate, will result in a SQL UPDATE

View File

@ -85,7 +85,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
boolean substitute = Versioning.seedVersion(
state,
persister.getVersionProperty(),
persister.getVersionType(),
persister.getVersionJavaTypeDescriptor(),
this
);
if ( substitute ) {
@ -138,7 +138,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
Object oldVersion;
if ( persister.isVersioned() ) {
oldVersion = persister.getVersion( entity );
Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this );
Object newVersion = Versioning.increment( oldVersion, persister.getVersionJavaTypeDescriptor(), this );
Versioning.setVersion( state, newVersion, persister );
persister.setPropertyValues( entity, state );
}

View File

@ -258,7 +258,6 @@ import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeHelper;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.spi.TypeConfiguration;
@ -2070,6 +2069,7 @@ public abstract class AbstractEntityPersister
boolean includeProperty(int propertyNumber);
}
@Override
public Object forceVersionIncrement(Object id, Object currentVersion, SharedSessionContractImplementor session) {
if ( !isVersioned() ) {
throw new AssertionFailure( "cannot force version increment on non-versioned entity" );
@ -2081,7 +2081,7 @@ public abstract class AbstractEntityPersister
throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" );
}
Object nextVersion = ((VersionType) getVersionType()).next( currentVersion, session );
Object nextVersion = getVersionJavaTypeDescriptor().next( currentVersion, session );
if ( LOG.isTraceEnabled() ) {
LOG.trace(
"Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + "; "
@ -4494,7 +4494,7 @@ public abstract class AbstractEntityPersister
}
public Comparator<?> getVersionComparator() {
return isVersioned() ? getVersionType().getComparator() : null;
return isVersioned() ? getVersionType().getJavaTypeDescriptor().getComparator() : null;
}
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -4522,10 +4522,10 @@ public abstract class AbstractEntityPersister
return !entityMetamodel.getIdentifierProperty().isVirtual();
}
public VersionType<?> getVersionType() {
public BasicType<?> getVersionType() {
return entityMetamodel.getVersionProperty() == null
? null
: (VersionType<?>) entityMetamodel.getVersionProperty().getType();
: (BasicType<?>) entityMetamodel.getVersionProperty().getType();
}
public int getVersionProperty() {

View File

@ -48,8 +48,9 @@ import org.hibernate.sql.ast.tree.from.RootTableGroupProducer;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
/**
* Contract describing mapping information and persistence logic for a particular strategy of entity mapping. A given
@ -364,7 +365,15 @@ public interface EntityPersister
*
* @return The type of the version property; or null, if not versioned.
*/
VersionType<?> getVersionType();
BasicType<?> getVersionType();
default VersionJavaTypeDescriptor<Object> getVersionJavaTypeDescriptor() {
final BasicType<?> versionType = getVersionType();
//noinspection unchecked
return versionType == null
? null
: (VersionJavaTypeDescriptor<Object>) versionType.getJavaTypeDescriptor();
}
/**
* If {@link #isVersioned()}, then what is the index of the property

View File

@ -314,7 +314,6 @@ import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
import org.hibernate.type.BasicType;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
import org.hibernate.type.spi.TypeConfiguration;
@ -711,7 +710,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
throw new SemanticException( "increment option specified for update of non-versioned entity" );
}
final VersionType<?> versionType = persister.getVersionType();
final BasicType<?> versionType = persister.getVersionType();
if ( versionType instanceof UserVersionType ) {
throw new SemanticException( "user-defined version types not supported for increment option" );
}
@ -728,30 +727,20 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
final ColumnReference versionColumn = targetColumnReferences.get( 0 );
final Expression value;
if ( isTimestampBasedVersion( versionType ) ) {
value = new VersionTypeSeedParameterSpecification( versionType );
if ( versionMapping.getJdbcMapping().getJdbcTypeDescriptor().isTemporal() ) {
value = new VersionTypeSeedParameterSpecification( versionType, persister.getVersionJavaTypeDescriptor() );
}
else {
final BasicValuedMapping basicValuedMapping = (BasicValuedMapping) versionType;
value = new BinaryArithmeticExpression(
versionColumn,
ADD,
new QueryLiteral<>( 1, basicValuedMapping ),
basicValuedMapping
new QueryLiteral<>( 1, versionType ),
versionType
);
}
assignmentConsumer.accept( new Assignment( versionColumn, value ) );
}
private boolean isTimestampBasedVersion(VersionType<?> versionType) {
if ( versionType instanceof BasicType<?> ) {
return ( (BasicType<?>) versionType ).getJdbcTypeDescriptor().isTemporal();
}
final Class<?> javaType = versionType.getReturnedClass();
return java.util.Date.class.isAssignableFrom( javaType )
|| Calendar.class.isAssignableFrom( javaType );
}
@Override
public List<Assignment> visitSetClause(SqmSetClause setClause) {
final List<Assignment> assignments = new ArrayList<>( setClause.getAssignments().size() );
@ -1024,8 +1013,10 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
);
if ( needsVersionInsert ) {
final VersionType versionType = entityDescriptor.getVersionType();
final Expression expression = new VersionTypeSeedParameterSpecification( versionType );
final Expression expression = new VersionTypeSeedParameterSpecification(
entityDescriptor.getVersionMapping().getJdbcMapping(),
entityDescriptor.getVersionJavaTypeDescriptor()
);
insertStatement.getSourceSelectStatement().forEachQuerySpec(
querySpec -> {
querySpec.getSelectClause().addSqlSelection(

View File

@ -12,7 +12,7 @@ import java.sql.SQLException;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
/**
* Parameter bind specification used for optimistic lock version seeding (from insert statements).
@ -20,15 +20,15 @@ import org.hibernate.type.VersionType;
* @author Steve Ebersole
*/
public class VersionTypeSeedParameterSpecification extends JdbcParameterImpl {
private final VersionType type;
private final VersionJavaTypeDescriptor<?> type;
/**
* Constructs a version seed parameter bind specification.
*
* @param type The version type.
*/
public VersionTypeSeedParameterSpecification(VersionType type) {
super( (JdbcMapping) type );
public VersionTypeSeedParameterSpecification(JdbcMapping jdbcMapping, VersionJavaTypeDescriptor<?> type) {
super( jdbcMapping );
this.type = type;
}
@ -38,6 +38,12 @@ public class VersionTypeSeedParameterSpecification extends JdbcParameterImpl {
int startPosition,
JdbcParameterBindings jdbcParamBindings,
ExecutionContext executionContext) throws SQLException {
type.nullSafeSet( statement, type.seed( executionContext.getSession() ), startPosition, executionContext.getSession() );
//noinspection unchecked
getJdbcMapping().getJdbcValueBinder().bind(
statement,
type.seed( executionContext.getSession() ),
startPosition,
executionContext.getSession()
);
}
}

View File

@ -51,8 +51,8 @@ import org.hibernate.sql.results.internal.NullValueAssembler;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.BasicType;
import org.hibernate.type.TypeHelper;
import org.hibernate.type.VersionType;
import static org.hibernate.internal.log.LoggingHelper.toLoggableString;
@ -517,7 +517,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
if ( version != null ) {
// null version means the object is in the process of being loaded somewhere else in the ResultSet
final VersionType<?> versionType = concreteDescriptor.getVersionType();
final BasicType<?> versionType = concreteDescriptor.getVersionType();
final Object currentVersion = versionAssembler.assemble( rowProcessingState );
if ( !versionType.isEqual( version, currentVersion ) ) {
final StatisticsImplementor statistics = rowProcessingState.getSession().getFactory().getStatistics();

View File

@ -33,9 +33,10 @@ import org.hibernate.tuple.entity.EntityBasedBasicAttribute;
import org.hibernate.tuple.entity.EntityBasedCompositionAttribute;
import org.hibernate.tuple.entity.VersionProperty;
import org.hibernate.type.AssociationType;
import org.hibernate.type.BasicType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
/**
* Responsible for generation of runtime metamodel {@link Property} representations.
@ -107,10 +108,11 @@ public final class PropertyFactory {
boolean lazyAvailable) {
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
//noinspection unchecked
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
mappedUnsavedValue,
getGetter( property ),
(VersionType) property.getType(),
( VersionJavaTypeDescriptor<Object>) ((BasicType<?>) property.getType()).getJavaTypeDescriptor(),
getConstructor( property.getPersistentClass() )
);

View File

@ -7,29 +7,19 @@
package org.hibernate.type;
import java.sql.Types;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* A type that maps between a {@link Types#VARBINARY VARBINARY} and {@code byte[]}
*
* Implementation of the {@link VersionType} interface should be considered deprecated.
* For binary entity versions/timestamps, {@link RowVersionType} should be used instead.
*
* @author Gavin King
* @author Steve Ebersole
*/
public class BinaryType
extends AbstractSingleColumnStandardBasicType<byte[]>
implements VersionType<byte[]>, AdjustableBasicType<byte[]> {
implements AdjustableBasicType<byte[]> {
public static final BinaryType INSTANCE = new BinaryType();
@ -46,47 +36,4 @@ public class BinaryType
return new String[] { getName(), "byte[]", byte[].class.getName() };
}
/**
* Generate an initial version.
*
* @param session The session from which this request originates.
* @return an instance of the type
* @deprecated use {@link RowVersionType} for binary entity versions/timestamps
*/
@Override
@Deprecated
public byte[] seed(SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which
// are completely db-generated values...
return null;
}
/**
* Increment the version.
*
* @param session The session from which this request originates.
* @param current the current version
* @return an instance of the type
* @deprecated use {@link RowVersionType} for binary entity versions/timestamps
*/
@Override
@Deprecated
public byte[] next(byte[] current, SharedSessionContractImplementor session) {
return current;
}
/**
* Get a comparator for version values.
*
* @return The comparator to use to compare different version values.
* @deprecated use {@link RowVersionType} for binary entity versions/timestamps
*/
@Override
@Deprecated
public Comparator<byte[]> getComparator() {
return PrimitiveByteArrayTypeDescriptor.INSTANCE.getComparator();
}
}

View File

@ -7,9 +7,7 @@
package org.hibernate.type;
import java.io.Serializable;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.ByteTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
@ -21,7 +19,7 @@ import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
*/
public class ByteType
extends AbstractSingleColumnStandardBasicType<Byte>
implements PrimitiveType<Byte>, DiscriminatorType<Byte>, VersionType<Byte> {
implements PrimitiveType<Byte>, DiscriminatorType<Byte> {
public static final ByteType INSTANCE = new ByteType();
@ -60,19 +58,4 @@ public class ByteType
public Byte fromStringValue(CharSequence xml) {
return fromString( xml );
}
@Override
public Byte next(Byte current, SharedSessionContractImplementor session) {
return (byte) ( current + 1 );
}
@Override
public Byte seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Comparator<Byte> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
}

View File

@ -7,18 +7,16 @@
package org.hibernate.type;
import java.util.Calendar;
import java.util.Comparator;
import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.type.descriptor.java.CalendarTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link Calendar}
*
@ -27,7 +25,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public class CalendarType
extends AbstractSingleColumnStandardBasicType<Calendar>
implements VersionType<Calendar>, AllowableTemporalParameterType<Calendar> {
implements AllowableTemporalParameterType<Calendar> {
public static final CalendarType INSTANCE = new CalendarType();
@ -45,21 +43,6 @@ public class CalendarType
return new String[] { getName(), Calendar.class.getName(), GregorianCalendar.class.getName() };
}
@Override
public Calendar next(Calendar current, SharedSessionContractImplementor session) {
return seed( session );
}
@Override
public Calendar seed(SharedSessionContractImplementor session) {
return Calendar.getInstance();
}
@Override
public Comparator<Calendar> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
@Override
public AllowableTemporalParameterType resolveTemporalPrecision(
TemporalType temporalPrecision,

View File

@ -12,7 +12,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import org.hibernate.HibernateException;
@ -30,6 +29,7 @@ import org.hibernate.type.descriptor.java.JavaTypedExpressable;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.internal.UserTypeJavaTypeWrapper;
import org.hibernate.type.internal.UserTypeSqlTypeAdapter;
import org.hibernate.type.internal.UserTypeVersionJavaTypeWrapper;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.Sized;
@ -52,7 +52,7 @@ import org.hibernate.usertype.UserVersionType;
*/
public class CustomType
extends AbstractType
implements BasicType, IdentifierType, DiscriminatorType, VersionType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware {
implements BasicType, IdentifierType, DiscriminatorType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware {
private final UserType<Object> userType;
private final String[] registrationKeys;
@ -84,6 +84,9 @@ public class CustomType
//noinspection rawtypes
this.mappedJavaTypeDescriptor = (BasicJavaDescriptor) ( (JavaTypedExpressable) userType ).getExpressableJavaTypeDescriptor();
}
else if ( userType instanceof UserVersionType ) {
this.mappedJavaTypeDescriptor = new UserTypeVersionJavaTypeWrapper<>( (UserVersionType) userType );
}
else {
this.mappedJavaTypeDescriptor = new UserTypeJavaTypeWrapper<>( userType );
}
@ -255,21 +258,6 @@ public class CustomType
return fromStringValue( sequence );
}
@Override
public Comparator getComparator() {
return (Comparator) getUserType();
}
@Override
public Object next(Object current, SharedSessionContractImplementor session) {
return ( (UserVersionType) getUserType() ).next( current, session );
}
@Override
public Object seed(SharedSessionContractImplementor session) {
return ( (UserVersionType) getUserType() ).seed( session );
}
@Override
public String toLoggableString(Object value, SessionFactoryImplementor factory) {
if ( value == null ) {

View File

@ -6,16 +6,15 @@
*/
package org.hibernate.type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.descriptor.java.DbTimestampJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.jboss.logging.Logger;
@ -38,6 +37,14 @@ public class DbTimestampType extends TimestampType {
DbTimestampType.class.getName()
);
public DbTimestampType() {
this( TimestampTypeDescriptor.INSTANCE, JdbcTimestampTypeDescriptor.INSTANCE );
}
public DbTimestampType(JdbcTypeDescriptor jdbcTypeDescriptor, JavaTypeDescriptor<Date> javaTypeDescriptor) {
super( jdbcTypeDescriptor, new DbTimestampJavaTypeDescriptor<>( (TemporalJavaTypeDescriptor<Date>) javaTypeDescriptor ) );
}
@Override
public String getName() {
return "dbtimestamp";
@ -48,97 +55,4 @@ public class DbTimestampType extends TimestampType {
return new String[] {getName()};
}
@Override
public Date seed(SharedSessionContractImplementor session) {
if ( session == null ) {
LOG.trace( "Incoming session was null; using current jvm time" );
return super.seed( null );
}
else if ( !session.getJdbcServices().getJdbcEnvironment().getDialect().supportsCurrentTimestampSelection() ) {
LOG.debug( "Falling back to vm-based timestamp, as dialect does not support current timestamp selection" );
return super.seed( session );
}
else {
return getCurrentTimestamp( session );
}
}
private Date getCurrentTimestamp(SharedSessionContractImplementor session) {
Dialect dialect = session.getJdbcServices().getJdbcEnvironment().getDialect();
String timestampSelectString = dialect.getCurrentTimestampSelectString();
if ( dialect.isCurrentTimestampSelectStringCallable() ) {
return useCallableStatement( timestampSelectString, session );
}
return usePreparedStatement( timestampSelectString, session );
}
private Timestamp usePreparedStatement(String timestampSelectString, SharedSessionContractImplementor session) {
PreparedStatement ps = null;
try {
ps = session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( timestampSelectString, false );
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
rs.next();
Timestamp ts = rs.getTimestamp( 1 );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Current timestamp retrieved from db : {0} (nanos={1}, time={2})",
ts,
ts.getNanos(),
ts.getTime()
);
}
return ts;
}
catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(
e,
"could not select current db timestamp",
timestampSelectString
);
}
finally {
if ( ps != null ) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( ps );
session.getJdbcCoordinator().afterStatementExecution();
}
}
}
private Timestamp useCallableStatement(String callString, SharedSessionContractImplementor session) {
CallableStatement cs = null;
try {
cs = (CallableStatement) session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( callString, true );
cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
session.getJdbcCoordinator().getResultSetReturn().execute( cs );
Timestamp ts = cs.getTimestamp( 1 );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Current timestamp retrieved from db : {0} (nanos={1}, time={2})",
ts,
ts.getNanos(),
ts.getTime()
);
}
return ts;
}
catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(
e,
"could not call current db timestamp function",
callString
);
}
finally {
if ( cs != null ) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( cs );
session.getJdbcCoordinator().afterStatementExecution();
}
}
}
}

View File

@ -8,18 +8,16 @@ package org.hibernate.type;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.Locale;
import jakarta.persistence.TemporalType;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.type.descriptor.java.InstantJavaDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link java.time.LocalDateTime}.
*
@ -27,7 +25,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public class InstantType
extends AbstractSingleColumnStandardBasicType<Instant>
implements VersionType<Instant>, AllowableTemporalParameterType<Instant> {
implements AllowableTemporalParameterType<Instant> {
/**
* Singleton access
*/
@ -39,22 +37,6 @@ public class InstantType
super( TimestampTypeDescriptor.INSTANCE, InstantJavaDescriptor.INSTANCE );
}
@Override
public Instant seed(SharedSessionContractImplementor session) {
return Instant.now();
}
@Override
public Instant next(Instant current, SharedSessionContractImplementor session) {
return Instant.now();
}
@Override
@SuppressWarnings("unchecked")
public Comparator<Instant> getComparator() {
return ComparableComparator.INSTANCE;
}
@Override
public String getName() {
return "instant";

View File

@ -7,9 +7,7 @@
package org.hibernate.type;
import java.io.Serializable;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.IntegerTypeDescriptor;
/**
@ -19,7 +17,7 @@ import org.hibernate.type.descriptor.java.IntegerTypeDescriptor;
* @author Steve Ebersole
*/
public class IntegerType extends AbstractSingleColumnStandardBasicType<Integer>
implements PrimitiveType<Integer>, DiscriminatorType<Integer>, VersionType<Integer> {
implements PrimitiveType<Integer>, DiscriminatorType<Integer> {
public static final IntegerType INSTANCE = new IntegerType();
@ -53,19 +51,4 @@ public class IntegerType extends AbstractSingleColumnStandardBasicType<Integer>
public Integer stringToObject(CharSequence sequence) {
return fromString( sequence );
}
@Override
public Integer seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Integer next(Integer current, SharedSessionContractImplementor session) {
return current + 1;
}
@Override
public Comparator<Integer> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
}

View File

@ -7,17 +7,15 @@
package org.hibernate.type;
import java.time.LocalDateTime;
import java.util.Comparator;
import jakarta.persistence.TemporalType;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.type.descriptor.java.LocalDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link LocalDateTime}.
*
@ -25,7 +23,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public class LocalDateTimeType
extends AbstractSingleColumnStandardBasicType<LocalDateTime>
implements VersionType<LocalDateTime>, AllowableTemporalParameterType<LocalDateTime> {
implements AllowableTemporalParameterType<LocalDateTime> {
/**
* Singleton access
*/
@ -45,22 +43,6 @@ public class LocalDateTimeType
return true;
}
@Override
public LocalDateTime seed(SharedSessionContractImplementor session) {
return LocalDateTime.now();
}
@Override
public LocalDateTime next(LocalDateTime current, SharedSessionContractImplementor session) {
return LocalDateTime.now();
}
@Override
@SuppressWarnings("unchecked")
public Comparator<LocalDateTime> getComparator() {
return ComparableComparator.INSTANCE;
}
@Override
public AllowableTemporalParameterType resolveTemporalPrecision(
TemporalType temporalPrecision,

View File

@ -7,9 +7,7 @@
package org.hibernate.type;
import java.io.Serializable;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.LongTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BigIntTypeDescriptor;
@ -21,7 +19,7 @@ import org.hibernate.type.descriptor.jdbc.BigIntTypeDescriptor;
*/
public class LongType
extends AbstractSingleColumnStandardBasicType<Long>
implements PrimitiveType<Long>, DiscriminatorType<Long>, VersionType<Long> {
implements PrimitiveType<Long>, DiscriminatorType<Long> {
public static final LongType INSTANCE = new LongType();
@ -56,19 +54,4 @@ public class LongType
return Long.valueOf( sequence.toString() );
}
@Override
public Long next(Long current, SharedSessionContractImplementor session) {
return current + 1L;
}
@Override
public Long seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Comparator<Long> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
}

View File

@ -7,24 +7,22 @@
package org.hibernate.type;
import java.time.OffsetDateTime;
import java.util.Comparator;
import jakarta.persistence.TemporalType;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.query.CastType;
import org.hibernate.type.descriptor.java.OffsetDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* @author Steve Ebersole
*/
public class OffsetDateTimeType
extends AbstractSingleColumnStandardBasicType<OffsetDateTime>
implements VersionType<OffsetDateTime>, AllowableTemporalParameterType<OffsetDateTime> {
implements AllowableTemporalParameterType<OffsetDateTime> {
/**
* Singleton access
@ -35,21 +33,6 @@ public class OffsetDateTimeType
super( TimestampWithTimeZoneDescriptor.INSTANCE, OffsetDateTimeJavaDescriptor.INSTANCE );
}
@Override
public OffsetDateTime seed(SharedSessionContractImplementor session) {
return OffsetDateTime.now();
}
@Override
public OffsetDateTime next(OffsetDateTime current, SharedSessionContractImplementor session) {
return OffsetDateTime.now();
}
@Override
public Comparator<OffsetDateTime> getComparator() {
return OffsetDateTime.timeLineOrder();
}
@Override
public String getName() {
return OffsetDateTime.class.getSimpleName();

View File

@ -6,9 +6,6 @@
*/
package org.hibernate.type;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.RowVersionTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
@ -21,8 +18,7 @@ import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
* @author Gail Badner
*/
public class RowVersionType
extends AbstractSingleColumnStandardBasicType<byte[]>
implements VersionType<byte[]> {
extends AbstractSingleColumnStandardBasicType<byte[]> {
public static final RowVersionType INSTANCE = new RowVersionType();
@ -39,22 +35,4 @@ public class RowVersionType
return new String[] { getName() };
}
@Override
public byte[] seed(SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which
// are completely db-generated values...
return null;
}
@Override
public byte[] next(byte[] current, SharedSessionContractImplementor session) {
return current;
}
@Override
public Comparator<byte[]> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
}

View File

@ -7,9 +7,7 @@
package org.hibernate.type;
import java.io.Serializable;
import java.util.Comparator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.ShortTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
@ -21,7 +19,7 @@ import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
*/
public class ShortType
extends AbstractSingleColumnStandardBasicType<Short>
implements PrimitiveType<Short>, DiscriminatorType<Short>, VersionType<Short> {
implements PrimitiveType<Short>, DiscriminatorType<Short> {
public static final ShortType INSTANCE = new ShortType();
@ -56,19 +54,4 @@ public class ShortType
return Short.valueOf( sequence.toString() );
}
@Override
public Short seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Short next(Short current, SharedSessionContractImplementor session) {
return (short) ( current + 1 );
}
@Override
public Comparator<Short> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
}

View File

@ -7,18 +7,19 @@
package org.hibernate.type;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.Date;
import jakarta.persistence.TemporalType;
import org.hibernate.HibernateException;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link Timestamp}
*
@ -27,7 +28,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public class TimestampType
extends AbstractSingleColumnStandardBasicType<Date>
implements VersionType<Date>, AllowableTemporalParameterType<Date> {
implements AllowableTemporalParameterType<Date> {
public static final TimestampType INSTANCE = new TimestampType();
@ -35,6 +36,10 @@ public class TimestampType
super( TimestampTypeDescriptor.INSTANCE, JdbcTimestampTypeDescriptor.INSTANCE );
}
protected TimestampType(JdbcTypeDescriptor jdbcTypeDescriptor, JavaTypeDescriptor<Date> javaTypeDescriptor) {
super( jdbcTypeDescriptor, javaTypeDescriptor );
}
@Override
public String getName() {
return "timestamp";
@ -45,21 +50,6 @@ public class TimestampType
return new String[] { getName(), Timestamp.class.getName(), Date.class.getName() };
}
@Override
public Date next(Date current, SharedSessionContractImplementor session) {
return seed( session );
}
@Override
public Date seed(SharedSessionContractImplementor session) {
return new Timestamp( System.currentTimeMillis() );
}
@Override
public Comparator<Date> getComparator() {
return getJavaTypeDescriptor().getComparator();
}
@Override
public Date fromStringValue(CharSequence xml) throws HibernateException {
return fromString( xml );

View File

@ -7,24 +7,22 @@
package org.hibernate.type;
import java.time.ZonedDateTime;
import java.util.Comparator;
import jakarta.persistence.TemporalType;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.ZonedDateTimeComparator;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
import org.hibernate.query.CastType;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
/**
* @author Steve Ebersole
*/
public class ZonedDateTimeType
extends AbstractSingleColumnStandardBasicType<ZonedDateTime>
implements VersionType<ZonedDateTime>, AllowableTemporalParameterType<ZonedDateTime> {
implements AllowableTemporalParameterType<ZonedDateTime> {
/**
* Singleton access
@ -32,23 +30,7 @@ public class ZonedDateTimeType
public static final ZonedDateTimeType INSTANCE = new ZonedDateTimeType();
public ZonedDateTimeType() {
super( TimestampWithTimeZoneDescriptor.INSTANCE, ZonedDateTimeJavaDescriptor.INSTANCE );
}
@Override
public ZonedDateTime seed(SharedSessionContractImplementor session) {
return ZonedDateTime.now();
}
@Override
public ZonedDateTime next(ZonedDateTime current, SharedSessionContractImplementor session) {
return ZonedDateTime.now();
}
@Override
@SuppressWarnings("unchecked")
public Comparator<ZonedDateTime> getComparator() {
return ZonedDateTimeComparator.INSTANCE;
super( TimestampWithTimeZoneDescriptor.INSTANCE, ZonedDateTimeJavaTypeDescriptor.INSTANCE );
}
@Override

View File

@ -10,6 +10,7 @@ import java.math.BigInteger;
import java.util.Locale;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.spi.Primitive;
@ -19,7 +20,9 @@ import org.hibernate.type.descriptor.java.spi.Primitive;
* @author Steve Ebersole
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
public class ByteTypeDescriptor extends AbstractClassTypeDescriptor<Byte> implements Primitive<Byte> {
public class ByteTypeDescriptor extends AbstractClassTypeDescriptor<Byte> implements Primitive<Byte>, VersionJavaTypeDescriptor<Byte>{
private static final Byte ZERO = (byte) 0;
public static final ByteTypeDescriptor INSTANCE = new ByteTypeDescriptor();
public ByteTypeDescriptor() {
@ -170,4 +173,13 @@ public class ByteTypeDescriptor extends AbstractClassTypeDescriptor<Byte> implem
)
);
}
@Override
public Byte next(Byte current, SharedSessionContractImplementor session) {
return (byte) ( current + 1 );
}
@Override
public Byte seed(SharedSessionContractImplementor session) {
return ZERO;
}
}

View File

@ -13,6 +13,7 @@ import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.compare.CalendarComparator;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -25,7 +26,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class CalendarTypeDescriptor extends AbstractTemporalTypeDescriptor<Calendar> {
public class CalendarTypeDescriptor extends AbstractTemporalTypeDescriptor<Calendar> implements VersionJavaTypeDescriptor<Calendar> {
public static final CalendarTypeDescriptor INSTANCE = new CalendarTypeDescriptor();
public static class CalendarMutabilityPlan extends MutableMutabilityPlan<Calendar> {
@ -158,4 +159,14 @@ public class CalendarTypeDescriptor extends AbstractTemporalTypeDescriptor<Calen
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public Calendar next(Calendar current, SharedSessionContractImplementor session) {
return seed( session );
}
@Override
public Calendar seed(SharedSessionContractImplementor session) {
return Calendar.getInstance();
}
}

View File

@ -0,0 +1,248 @@
/*
* 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.lang.reflect.Type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Comparator;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
import jakarta.persistence.TemporalType;
/**
* Wrapper Java type descriptor for that uses the database timestamp as seed value for versions.
*
* @author Christian Beikov
*/
public class DbTimestampJavaTypeDescriptor<T> implements VersionJavaTypeDescriptor<T>, TemporalJavaTypeDescriptor<T> {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
DbTimestampJavaTypeDescriptor.class.getName()
);
private final TemporalJavaTypeDescriptor<T> delegate;
public DbTimestampJavaTypeDescriptor(TemporalJavaTypeDescriptor<T> delegate) {
this.delegate = delegate;
}
@Override
public T next(T current, SharedSessionContractImplementor session) {
return seed( session );
}
@Override
@SuppressWarnings("unchecked")
public T seed(SharedSessionContractImplementor session) {
if ( session == null ) {
LOG.trace( "Incoming session was null; using current jvm time" );
return ((VersionJavaTypeDescriptor<T>) delegate).seed( null );
}
else if ( !session.getJdbcServices().getJdbcEnvironment().getDialect().supportsCurrentTimestampSelection() ) {
LOG.debug( "Falling back to vm-based timestamp, as dialect does not support current timestamp selection" );
return ((VersionJavaTypeDescriptor<T>) delegate).seed( session );
}
else {
return getCurrentTimestamp( session );
}
}
private T getCurrentTimestamp(SharedSessionContractImplementor session) {
Dialect dialect = session.getJdbcServices().getJdbcEnvironment().getDialect();
String timestampSelectString = dialect.getCurrentTimestampSelectString();
if ( dialect.isCurrentTimestampSelectStringCallable() ) {
return useCallableStatement( timestampSelectString, session );
}
return usePreparedStatement( timestampSelectString, session );
}
private T usePreparedStatement(String timestampSelectString, SharedSessionContractImplementor session) {
PreparedStatement ps = null;
try {
ps = session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( timestampSelectString, false );
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
rs.next();
Timestamp ts = rs.getTimestamp( 1 );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Current timestamp retrieved from db : {0} (nanos={1}, time={2})",
ts,
ts.getNanos(),
ts.getTime()
);
}
return delegate.wrap( ts, session );
}
catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(
e,
"could not select current db timestamp",
timestampSelectString
);
}
finally {
if ( ps != null ) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( ps );
session.getJdbcCoordinator().afterStatementExecution();
}
}
}
private T useCallableStatement(String callString, SharedSessionContractImplementor session) {
CallableStatement cs = null;
try {
cs = (CallableStatement) session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( callString, true );
cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
session.getJdbcCoordinator().getResultSetReturn().execute( cs );
Timestamp ts = cs.getTimestamp( 1 );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Current timestamp retrieved from db : {0} (nanos={1}, time={2})",
ts,
ts.getNanos(),
ts.getTime()
);
}
return delegate.wrap( ts, session );
}
catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(
e,
"could not call current db timestamp function",
callString
);
}
finally {
if ( cs != null ) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( cs );
session.getJdbcCoordinator().afterStatementExecution();
}
}
}
@Override
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators indicators) {
return delegate.getRecommendedJdbcType( indicators );
}
@Override
public T fromString(CharSequence string) {
return delegate.fromString( string );
}
@Override
public Type getJavaType() {
return delegate.getJavaType();
}
@Override
public MutabilityPlan<T> getMutabilityPlan() {
return delegate.getMutabilityPlan();
}
@Override
public long getDefaultSqlLength(Dialect dialect) {
return delegate.getDefaultSqlLength( dialect );
}
@Override
public long getLongSqlLength() {
return delegate.getLongSqlLength();
}
@Override
public int getDefaultSqlPrecision(Dialect dialect) {
return delegate.getDefaultSqlPrecision( dialect );
}
@Override
public int getDefaultSqlScale() {
return delegate.getDefaultSqlScale();
}
@Override
public Comparator<T> getComparator() {
return delegate.getComparator();
}
@Override
public int extractHashCode(T value) {
return delegate.extractHashCode( value );
}
@Override
public boolean areEqual(T one, T another) {
return delegate.areEqual( one, another );
}
@Override
public String extractLoggableRepresentation(T value) {
return delegate.extractLoggableRepresentation( value );
}
@Override
public String toString(T value) {
return delegate.toString( value );
}
@Override
public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
return delegate.unwrap( value, type, options );
}
@Override
public <X> T wrap(X value, WrapperOptions options) {
return delegate.wrap( value, options );
}
@Override
public <X> T coerce(X value, CoercionContext coercionContext) {
return delegate.coerce( value, coercionContext );
}
@Override
public Class<T> getJavaTypeClass() {
return delegate.getJavaTypeClass();
}
@Override
public String getCheckCondition(String columnName, JdbcTypeDescriptor sqlType, Dialect dialect) {
return delegate.getCheckCondition( columnName, sqlType, dialect );
}
@Override
public TemporalType getPrecision() {
return delegate.getPrecision();
}
@Override
public <X> TemporalJavaTypeDescriptor<X> resolveTypeForPrecision(
TemporalType precision,
TypeConfiguration typeConfiguration) {
return delegate.resolveTypeForPrecision( precision, typeConfiguration );
}
}

View File

@ -19,6 +19,7 @@ import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
@ -30,7 +31,8 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class InstantJavaDescriptor extends AbstractTemporalTypeDescriptor<Instant> {
public class InstantJavaDescriptor extends AbstractTemporalTypeDescriptor<Instant>
implements VersionJavaTypeDescriptor<Instant> {
/**
* Singleton access
*/
@ -185,4 +187,15 @@ public class InstantJavaDescriptor extends AbstractTemporalTypeDescriptor<Instan
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public Instant seed(SharedSessionContractImplementor session) {
return Instant.now();
}
@Override
public Instant next(Instant current, SharedSessionContractImplementor session) {
return Instant.now();
}
}

View File

@ -11,6 +11,7 @@ import java.math.BigInteger;
import java.util.Locale;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.spi.Primitive;
@ -19,7 +20,10 @@ import org.hibernate.type.descriptor.java.spi.Primitive;
*
* @author Steve Ebersole
*/
public class IntegerTypeDescriptor extends AbstractClassTypeDescriptor<Integer> implements Primitive<Integer> {
public class IntegerTypeDescriptor extends AbstractClassTypeDescriptor<Integer>
implements Primitive<Integer>, VersionJavaTypeDescriptor<Integer> {
public static final Integer ZERO = 0;
public static final IntegerTypeDescriptor INSTANCE = new IntegerTypeDescriptor();
public IntegerTypeDescriptor() {
@ -175,4 +179,15 @@ public class IntegerTypeDescriptor extends AbstractClassTypeDescriptor<Integer>
)
);
}
@Override
public Integer seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Integer next(Integer current, SharedSessionContractImplementor session) {
return current + 1;
}
}

View File

@ -21,6 +21,7 @@ import jakarta.persistence.TemporalType;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
@ -32,7 +33,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class JdbcTimestampTypeDescriptor extends AbstractTemporalTypeDescriptor<Date> {
public class JdbcTimestampTypeDescriptor extends AbstractTemporalTypeDescriptor<Date> implements VersionJavaTypeDescriptor<Date> {
public static final JdbcTimestampTypeDescriptor INSTANCE = new JdbcTimestampTypeDescriptor();
@SuppressWarnings("WeakerAccess")
@ -208,4 +209,15 @@ public class JdbcTimestampTypeDescriptor extends AbstractTemporalTypeDescriptor<
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public Date next(Date current, SharedSessionContractImplementor session) {
return seed( session );
}
@Override
public Date seed(SharedSessionContractImplementor session) {
return new Timestamp( System.currentTimeMillis() );
}
}

View File

@ -18,6 +18,7 @@ import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
@ -29,7 +30,8 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class LocalDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<LocalDateTime> {
public class LocalDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<LocalDateTime>
implements VersionJavaTypeDescriptor<LocalDateTime> {
/**
* Singleton access
*/
@ -160,4 +162,14 @@ public class LocalDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public LocalDateTime seed(SharedSessionContractImplementor session) {
return LocalDateTime.now();
}
@Override
public LocalDateTime next(LocalDateTime current, SharedSessionContractImplementor session) {
return LocalDateTime.now();
}
}

View File

@ -11,6 +11,7 @@ import java.math.BigInteger;
import java.util.Locale;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.spi.Primitive;
@ -19,7 +20,10 @@ import org.hibernate.type.descriptor.java.spi.Primitive;
*
* @author Steve Ebersole
*/
public class LongTypeDescriptor extends AbstractClassTypeDescriptor<Long> implements Primitive<Long> {
public class LongTypeDescriptor extends AbstractClassTypeDescriptor<Long>
implements Primitive<Long>, VersionJavaTypeDescriptor<Long> {
private static final Long ZERO = (long) 0;
public static final LongTypeDescriptor INSTANCE = new LongTypeDescriptor();
public LongTypeDescriptor() {
@ -175,4 +179,14 @@ public class LongTypeDescriptor extends AbstractClassTypeDescriptor<Long> implem
public int getDefaultSqlScale() {
return 0;
}
@Override
public Long next(Long current, SharedSessionContractImplementor session) {
return current + 1L;
}
@Override
public Long seed(SharedSessionContractImplementor session) {
return ZERO;
}
}

View File

@ -13,12 +13,14 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.DateTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -32,7 +34,8 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class OffsetDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<OffsetDateTime> {
public class OffsetDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<OffsetDateTime>
implements VersionJavaTypeDescriptor<OffsetDateTime> {
/**
* Singleton access
*/
@ -200,4 +203,19 @@ public class OffsetDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public OffsetDateTime seed(SharedSessionContractImplementor session) {
return OffsetDateTime.now();
}
@Override
public OffsetDateTime next(OffsetDateTime current, SharedSessionContractImplementor session) {
return OffsetDateTime.now();
}
@Override
public Comparator<OffsetDateTime> getComparator() {
return OffsetDateTime.timeLineOrder();
}
}

View File

@ -16,6 +16,7 @@ import java.util.Comparator;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions;
@ -24,7 +25,8 @@ import org.hibernate.type.descriptor.WrapperOptions;
*
* @author Steve Ebersole
*/
public class PrimitiveByteArrayTypeDescriptor extends AbstractClassTypeDescriptor<byte[]> {
public class PrimitiveByteArrayTypeDescriptor extends AbstractClassTypeDescriptor<byte[]>
implements VersionJavaTypeDescriptor<byte[]> {
public static final PrimitiveByteArrayTypeDescriptor INSTANCE = new PrimitiveByteArrayTypeDescriptor();
@SuppressWarnings({ "unchecked" })
@ -132,4 +134,18 @@ public class PrimitiveByteArrayTypeDescriptor extends AbstractClassTypeDescripto
throw unknownWrap( value.getClass() );
}
@Override
public byte[] seed(SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which
// are completely db-generated values...
return null;
}
@Override
public byte[] next(byte[] current, SharedSessionContractImplementor session) {
return current;
}
}

View File

@ -16,6 +16,7 @@ import java.util.Comparator;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.compare.RowVersionComparator;
import org.hibernate.type.descriptor.WrapperOptions;
@ -25,7 +26,8 @@ import org.hibernate.type.descriptor.WrapperOptions;
* @author Steve Ebersole
* @author Gail Badner
*/
public class RowVersionTypeDescriptor extends AbstractClassTypeDescriptor<byte[]> {
public class RowVersionTypeDescriptor extends AbstractClassTypeDescriptor<byte[]>
implements VersionJavaTypeDescriptor<byte[]> {
public static final RowVersionTypeDescriptor INSTANCE = new RowVersionTypeDescriptor();
@SuppressWarnings({ "unchecked" })
@ -128,4 +130,18 @@ public class RowVersionTypeDescriptor extends AbstractClassTypeDescriptor<byte[]
throw unknownWrap( value.getClass() );
}
@Override
public byte[] seed(SharedSessionContractImplementor session) {
// Note : simply returns null for seed() and next() as the only known
// application of binary types for versioning is for use with the
// TIMESTAMP datatype supported by Sybase and SQL Server, which
// are completely db-generated values...
return null;
}
@Override
public byte[] next(byte[] current, SharedSessionContractImplementor session) {
return current;
}
}

View File

@ -10,6 +10,7 @@ import java.math.BigInteger;
import java.util.Locale;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.spi.Primitive;
@ -18,7 +19,10 @@ import org.hibernate.type.descriptor.java.spi.Primitive;
*
* @author Steve Ebersole
*/
public class ShortTypeDescriptor extends AbstractClassTypeDescriptor<Short> implements Primitive<Short> {
public class ShortTypeDescriptor extends AbstractClassTypeDescriptor<Short>
implements Primitive<Short>, VersionJavaTypeDescriptor<Short> {
private static final Short ZERO = (short) 0;
public static final ShortTypeDescriptor INSTANCE = new ShortTypeDescriptor();
public ShortTypeDescriptor() {
@ -167,4 +171,13 @@ public class ShortTypeDescriptor extends AbstractClassTypeDescriptor<Short> impl
)
);
}
@Override
public Short seed(SharedSessionContractImplementor session) {
return ZERO;
}
@Override
public Short next(Short current, SharedSessionContractImplementor session) {
return (short) ( current + 1 );
}
}

View File

@ -4,19 +4,16 @@
* 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;
import java.util.Comparator;
package org.hibernate.type.descriptor.java;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Additional contract for types which may be used to version (and optimistic lock) data.
*
* @author Gavin King
* @author Steve Ebersole
* @author Christian Beikov
*/
public interface VersionType<T> extends Type {
public interface VersionJavaTypeDescriptor<T> extends JavaTypeDescriptor<T> {
/**
* Generate an initial version.
*
@ -34,10 +31,4 @@ public interface VersionType<T> extends Type {
*/
T next(T current, SharedSessionContractImplementor session);
/**
* Get a comparator for version values.
*
* @return The comparator to use to compare different version values.
*/
Comparator<T> getComparator();
}

View File

@ -13,12 +13,15 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.ZonedDateTimeComparator;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.DateTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -32,14 +35,14 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public class ZonedDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<ZonedDateTime> {
public class ZonedDateTimeJavaTypeDescriptor extends AbstractTemporalTypeDescriptor<ZonedDateTime> implements VersionJavaTypeDescriptor<ZonedDateTime> {
/**
* Singleton access
*/
public static final ZonedDateTimeJavaDescriptor INSTANCE = new ZonedDateTimeJavaDescriptor();
public static final ZonedDateTimeJavaTypeDescriptor INSTANCE = new ZonedDateTimeJavaTypeDescriptor();
@SuppressWarnings("unchecked")
public ZonedDateTimeJavaDescriptor() {
public ZonedDateTimeJavaTypeDescriptor() {
super( ZonedDateTime.class, ImmutableMutabilityPlan.INSTANCE );
}
@ -199,4 +202,19 @@ public class ZonedDateTimeJavaDescriptor extends AbstractTemporalTypeDescriptor<
public int getDefaultSqlPrecision(Dialect dialect) {
return dialect.getDefaultTimestampPrecision();
}
@Override
public ZonedDateTime seed(SharedSessionContractImplementor session) {
return ZonedDateTime.now();
}
@Override
public ZonedDateTime next(ZonedDateTime current, SharedSessionContractImplementor session) {
return ZonedDateTime.now();
}
@Override
public Comparator<ZonedDateTime> getComparator() {
return ZonedDateTimeComparator.INSTANCE;
}
}

View File

@ -69,7 +69,7 @@ import org.hibernate.type.descriptor.java.TimeZoneTypeDescriptor;
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
import org.hibernate.type.descriptor.java.ZoneOffsetJavaDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaTypeDescriptor;
/**
*
@ -115,7 +115,7 @@ public class JavaTypeDescriptorBaseline {
target.addBaselineDescriptor( LocalTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( ZonedDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( ZonedDateTimeJavaTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( CalendarTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( DateTypeDescriptor.INSTANCE );

View File

@ -28,7 +28,7 @@ import org.hibernate.usertype.UserType;
* @author Steve Ebersole
*/
public class UserTypeJavaTypeWrapper<J> implements BasicJavaDescriptor<J> {
private final UserType<J> userType;
protected final UserType<J> userType;
private final MutabilityPlan<J> mutabilityPlan;
private final Comparator<J> comparator;

View File

@ -0,0 +1,32 @@
/*
* 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.internal;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.VersionJavaTypeDescriptor;
import org.hibernate.usertype.UserVersionType;
/**
*
* @author Christian Beikov
*/
public class UserTypeVersionJavaTypeWrapper<J> extends UserTypeJavaTypeWrapper<J> implements VersionJavaTypeDescriptor<J> {
public UserTypeVersionJavaTypeWrapper(UserVersionType<J> userType) {
super( userType );
}
@Override
public J seed(SharedSessionContractImplementor session) {
return ( (UserVersionType<J>) userType ).seed( session );
}
@Override
public J next(J current, SharedSessionContractImplementor session) {
return ( (UserVersionType<J>) userType ).next( current, session );
}
}

View File

@ -15,7 +15,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
*
* @author Gavin King
*/
public interface UserVersionType extends UserType, Comparator {
public interface UserVersionType<T> extends UserType<T>, Comparator<T> {
/**
* Generate an initial version.
*
@ -24,7 +24,7 @@ public interface UserVersionType extends UserType, Comparator {
* the "unsaved value" of entities.
* @return an instance of the type
*/
Object seed(SharedSessionContractImplementor session);
T seed(SharedSessionContractImplementor session);
/**
* Increment the version.
@ -33,5 +33,5 @@ public interface UserVersionType extends UserType, Comparator {
* @param current the current version
* @return an instance of the type
*/
Object next(Object current, SharedSessionContractImplementor session);
T next(T current, SharedSessionContractImplementor session);
}

View File

@ -64,9 +64,9 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.BasicType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@ -237,7 +237,7 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
}
@Override
public VersionType getVersionType() {
public BasicType<?> getVersionType() {
return null;
}

View File

@ -62,8 +62,8 @@ import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.junit.jupiter.api.Assertions;
@ -262,7 +262,7 @@ public class PersisterClassProviderTest {
}
@Override
public VersionType getVersionType() {
public BasicType<?> getVersionType() {
return null;
}

View File

@ -63,9 +63,9 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
public class CustomPersister implements EntityPersister {
@ -295,7 +295,7 @@ public class CustomPersister implements EntityPersister {
/**
* @see EntityPersister#getVersionType()
*/
public VersionType getVersionType() {
public BasicType<?> getVersionType() {
return null;
}

View File

@ -9,7 +9,7 @@ package org.hibernate.orm.test.mapping.type.java;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaTypeDescriptor;
/**
* @author Jordan Gigov
@ -20,7 +20,7 @@ public class ZonedDateTimeDescriptorTest extends AbstractDescriptorTest<ZonedDat
final ZonedDateTime different = ZonedDateTime.of( LocalDateTime.of( 2016, 10, 8, 15, 13 ), ZoneId.of( "EET" ) );
public ZonedDateTimeDescriptorTest() {
super(ZonedDateTimeJavaDescriptor.INSTANCE);
super( ZonedDateTimeJavaTypeDescriptor.INSTANCE);
}
@Override

View File

@ -21,8 +21,9 @@ import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.type.BasicType;
import org.hibernate.type.RowVersionType;
import org.hibernate.type.VersionType;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@ -36,7 +37,7 @@ public class SybaseTimestampComparisonAnnotationsTest extends BaseCoreFunctional
@Test
@TestForIssue( jiraKey = "HHH-10413" )
public void testComparableTimestamps() {
final VersionType versionType =
final BasicType<?> versionType =
sessionFactory().getEntityPersister( Thing.class.getName() ).getVersionType();
assertSame( RowVersionType.INSTANCE, versionType );

View File

@ -16,9 +16,10 @@ import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.type.BasicType;
import org.hibernate.type.BinaryType;
import org.hibernate.type.RowVersionType;
import org.hibernate.type.VersionType;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
@ -225,7 +226,7 @@ public class SybaseTimestampVersioningTest extends BaseCoreFunctionalTestCase {
@Test
@TestForIssue( jiraKey = "HHH-10413" )
public void testComparableTimestamps() {
final VersionType versionType =
final BasicType<?> versionType =
sessionFactory().getEntityPersister( User.class.getName() ).getVersionType();
assertSame( RowVersionType.INSTANCE, versionType );