Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public Class<?> getPreferredJavaTypeClass(WrapperOptions options) {
return Duration.class;
}

@Override
public boolean isComparable() {
return true;
}

@Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
return (appender, value, dialect, wrapperOptions) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public int getDefaultSqlTypeCode() {
return SqlTypes.INTERVAL_SECOND;
}

@Override
public boolean isComparable() {
return true;
}

@Override
public Class<?> getPreferredJavaTypeClass(WrapperOptions options) {
return Duration.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,10 @@ private int validateArgument(int paramNumber, JdbcMappingContainer expressionTyp
final int jdbcTypeCount = expressionType.getJdbcTypeCount();
for ( int i = 0; i < jdbcTypeCount; i++ ) {
final JdbcMapping mapping = expressionType.getJdbcMapping( i );
FunctionParameterType type = paramNumber < types.length ? types[paramNumber++] : types[types.length - 1];
final FunctionParameterType type =
paramNumber < types.length
? types[paramNumber++]
: types[types.length - 1];
if ( type != null ) {
checkArgumentType(
paramNumber,
Expand Down
139 changes: 63 additions & 76 deletions hibernate-core/src/main/java/org/hibernate/type/CustomType.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
Expand All @@ -26,14 +25,16 @@
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.internal.UserTypeJavaTypeWrapper;
import org.hibernate.type.internal.UserTypeSqlTypeAdapter;
import org.hibernate.type.internal.UserTypeJdbcTypeAdapter;
import org.hibernate.type.internal.UserTypeVersionJavaTypeWrapper;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.LoggableUserType;
import org.hibernate.usertype.UserType;
import org.hibernate.usertype.UserVersionType;

import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY;

/**
* Adapts {@link UserType} to the generic {@link Type} interface, in order
* to isolate user code from changes in the internal Type contracts.
Expand Down Expand Up @@ -63,36 +64,22 @@ public class CustomType<J>
private final JdbcLiteralFormatter<J> jdbcLiteralFormatter;

public CustomType(UserType<J> userType, TypeConfiguration typeConfiguration) throws MappingException {
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
this( userType, EMPTY_STRING_ARRAY, typeConfiguration );
}

public CustomType(UserType<J> userType, String[] registrationKeys, TypeConfiguration typeConfiguration)
throws MappingException {
public CustomType(UserType<J> userType, String[] registrationKeys, TypeConfiguration typeConfiguration) {
this.userType = userType;
name = userType.getClass().getName();

if ( userType instanceof JavaType<?> ) {
//noinspection unchecked
mappedJavaType = (JavaType<J>) userType;
}
else if ( userType instanceof JavaTypedExpressible) {
//noinspection unchecked
mappedJavaType = ( (JavaTypedExpressible<J>) userType ).getExpressibleJavaType();
}
else if ( userType instanceof UserVersionType ) {
mappedJavaType = new UserTypeVersionJavaTypeWrapper<>( (UserVersionType<J>) userType );
}
else {
mappedJavaType = new UserTypeJavaTypeWrapper<>( userType );
}
mappedJavaType = getMappedJavaType( userType );

final BasicValueConverter<J, Object> valueConverter = userType.getValueConverter();
if ( valueConverter != null ) {
final BasicValueConverter<J, Object> converter = userType.getValueConverter();
if ( converter != null ) {
// When an explicit value converter is given,
// we configure the custom type to use that instead of adapters that delegate to UserType.
// This is necessary to support selecting a column with multiple domain type representations.
jdbcType = userType.getJdbcType( typeConfiguration );
jdbcJavaType = valueConverter.getRelationalJavaType();
jdbcJavaType = converter.getRelationalJavaType();
//noinspection unchecked
valueExtractor = (ValueExtractor<J>) jdbcType.getExtractor( jdbcJavaType );
//noinspection unchecked
Expand All @@ -102,18 +89,34 @@ else if ( userType instanceof UserVersionType ) {
}
else {
// create a JdbcType adapter that uses the UserType binder/extract handling
jdbcType = new UserTypeSqlTypeAdapter<>( userType, mappedJavaType, typeConfiguration );
jdbcType = new UserTypeJdbcTypeAdapter<>( userType, mappedJavaType );
jdbcJavaType = jdbcType.getJdbcRecommendedJavaTypeMapping( null, null, typeConfiguration );
valueExtractor = jdbcType.getExtractor( mappedJavaType );
valueBinder = jdbcType.getBinder( mappedJavaType );
jdbcLiteralFormatter = userType instanceof EnhancedUserType
? jdbcType.getJdbcLiteralFormatter( mappedJavaType )
: null;
jdbcLiteralFormatter =
userType instanceof EnhancedUserType ? jdbcType.getJdbcLiteralFormatter( mappedJavaType ) : null;
}

this.registrationKeys = registrationKeys;
}

private JavaType<J> getMappedJavaType(UserType<J> userType) {
if ( userType instanceof JavaType<?> ) {
//noinspection unchecked
return (JavaType<J>) userType;
}
else if ( userType instanceof JavaTypedExpressible<?> ) {
//noinspection unchecked
return ( (JavaTypedExpressible<J>) userType).getExpressibleJavaType();
}
else if ( userType instanceof UserVersionType<J> userVersionType ) {
return new UserTypeVersionJavaTypeWrapper<>( userVersionType );
}
else {
return new UserTypeJavaTypeWrapper<>( userType );
}
}

public UserType<J> getUserType() {
return userType;
}
Expand Down Expand Up @@ -176,13 +179,8 @@ public Object assemble(Serializable cached, SharedSessionContractImplementor ses
// in which case we will try to use a converter for assembling,
// or if that doesn't exist, simply use the relational value as is
if ( assembled == null && cached != null ) {
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) {
return cached;
}
else {
return valueConverter.toDomainValue( cached );
}
final BasicValueConverter<J, Object> converter = getUserType().getValueConverter();
return converter == null ? cached : converter.toDomainValue( cached );
}
return assembled;
}
Expand All @@ -193,7 +191,7 @@ public Serializable disassemble(Object value, SharedSessionContractImplementor s
}

@Override
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException {
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) {
return disassembleForCache( value );
}

Expand All @@ -204,27 +202,19 @@ private Serializable disassembleForCache(Object value) {
// in which case we will try to use a converter for disassembling,
// or if that doesn't exist, simply use the domain value as is
if ( disassembled == null ){
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) {
return disassembled;
}
else {
return (Serializable) valueConverter.toRelationalValue( (J) value );
}
final BasicValueConverter<J, Object> converter = getUserType().getValueConverter();
return converter == null ? disassembled : (Serializable) converter.toRelationalValue( (J) value );
}
else {
return disassembled;
}
return disassembled;
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
// Use the value converter if available for conversion to the jdbc representation
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
if ( valueConverter == null ) {
return value;
}
else {
return valueConverter.toRelationalValue( (J) value );
}
final BasicValueConverter<J, Object> converter = getUserType().getValueConverter();
return converter == null ? value : converter.toRelationalValue( (J) value );
}

@Override
Expand All @@ -240,12 +230,7 @@ public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedS
}
else {
cacheKey.addValue( disassembled );
if ( value == null ) {
cacheKey.addHashCode( 0 );
}
else {
cacheKey.addHashCode( getUserType().hashCode( (J) value ) );
}
cacheKey.addHashCode( value == null ? 0 : getUserType().hashCode( (J) value ) );
}
}

Expand All @@ -255,7 +240,7 @@ public Object replace(
Object target,
SharedSessionContractImplementor session,
Object owner,
Map<Object, Object> copyCache) throws HibernateException {
Map<Object, Object> copyCache) {
return getUserType().replace( (J) original, (J) target, owner );
}

Expand Down Expand Up @@ -302,8 +287,8 @@ public String toLoggableString(Object value, SessionFactoryImplementor factory)
if ( value == null ) {
return "null";
}
else if ( userType instanceof LoggableUserType ) {
return ( (LoggableUserType) userType ).toLoggableString( value, factory );
else if ( userType instanceof LoggableUserType loggableUserType ) {
return loggableUserType.toLoggableString( value, factory );
}
else if ( userType instanceof EnhancedUserType<?> ) {
return ( (EnhancedUserType<Object>) userType ).toString( value );
Expand All @@ -315,32 +300,32 @@ else if ( userType instanceof EnhancedUserType<?> ) {

@Override
public boolean[] toColumnNullness(Object value, MappingContext mapping) {
boolean[] result = new boolean[ getColumnSpan(mapping) ];
final boolean[] result = new boolean[ getColumnSpan(mapping) ];
if ( value != null ) {
Arrays.fill(result, true);
Arrays.fill( result, true );
}
return result;
}

@Override
public boolean isDirty(Object old, Object current, boolean[] checkable, SharedSessionContractImplementor session)
throws HibernateException {
return checkable[0] && isDirty(old, current, session);
return checkable[0] && isDirty( old, current, session );
}

@Override
public boolean canDoSetting() {
if ( getUserType() instanceof ProcedureParameterNamedBinder ) {
return ((ProcedureParameterNamedBinder<?>) getUserType() ).canDoSetting();
}
return false;
return getUserType() instanceof ProcedureParameterNamedBinder<?> procedureParameterNamedBinder
&& procedureParameterNamedBinder.canDoSetting();
}

@Override
public void nullSafeSet(
CallableStatement statement, J value, String name, SharedSessionContractImplementor session) throws SQLException {
public void nullSafeSet(CallableStatement statement, J value, String name, SharedSessionContractImplementor session)
throws SQLException {
if ( canDoSetting() ) {
((ProcedureParameterNamedBinder<J>) getUserType() ).nullSafeSet( statement, value, name, session );
//noinspection unchecked
( (ProcedureParameterNamedBinder<J>) getUserType() )
.nullSafeSet( statement, value, name, session );
}
else {
throw new UnsupportedOperationException(
Expand All @@ -351,17 +336,17 @@ public void nullSafeSet(

@Override
public boolean canDoExtraction() {
if ( getUserType() instanceof ProcedureParameterExtractionAware ) {
return ((ProcedureParameterExtractionAware<?>) getUserType() ).canDoExtraction();
}
return false;
return getUserType() instanceof ProcedureParameterExtractionAware<?> procedureParameterExtractionAware
&& procedureParameterExtractionAware.canDoExtraction();
}

@Override
public J extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session) throws SQLException {
public J extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session)
throws SQLException {
if ( canDoExtraction() ) {
//noinspection unchecked
return ((ProcedureParameterExtractionAware<J>) getUserType() ).extract( statement, startIndex, session );
return ((ProcedureParameterExtractionAware<J>) getUserType() )
.extract( statement, startIndex, session );
}
else {
throw new UnsupportedOperationException(
Expand All @@ -375,7 +360,8 @@ public J extract(CallableStatement statement, String paramName, SharedSessionCon
throws SQLException {
if ( canDoExtraction() ) {
//noinspection unchecked
return ((ProcedureParameterExtractionAware<J>) getUserType() ).extract( statement, paramName, session );
return ((ProcedureParameterExtractionAware<J>) getUserType() )
.extract( statement, paramName, session );
}
else {
throw new UnsupportedOperationException(
Expand All @@ -391,7 +377,8 @@ public int hashCode() {

@Override
public boolean equals(Object obj) {
return ( obj instanceof CustomType ) && getUserType().equals( ( (CustomType<?>) obj ).getUserType() );
return obj instanceof CustomType<?> customType
&& getUserType().equals( customType.getUserType() );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,26 @@ public String toString(Duration value) {
if ( value == null ) {
return null;
}
String seconds = String.valueOf( value.getSeconds() );
String nanos = String.valueOf( value.getNano() );
String zeros = StringHelper.repeat( '0', 9 - nanos.length() );
else {
final String seconds = String.valueOf( value.getSeconds() );
final String nanos = String.valueOf( value.getNano() );
final String zeros = StringHelper.repeat( '0', 9 - nanos.length() );
return seconds + zeros + nanos;
}
}

@Override
public Duration fromString(CharSequence string) {
if ( string == null ) {
return null;
}
int cutoff = string.length() - 9;
return Duration.ofSeconds(
Long.parseLong( string.subSequence( 0, cutoff ).toString() ),
Long.parseLong( string.subSequence( cutoff, string.length() ).toString() )
);
else {
final int cutoff = string.length() - 9;
return Duration.ofSeconds(
Long.parseLong( string.subSequence( 0, cutoff ).toString() ),
Long.parseLong( string.subSequence( cutoff, string.length() ).toString() )
);
}
}

@Override
Expand Down
Loading
Loading