diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/NamedConverterResolution.java b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/NamedConverterResolution.java index f90478a359..54f1b1e84d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/NamedConverterResolution.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/NamedConverterResolution.java @@ -127,11 +127,11 @@ public class NamedConverterResolution implements BasicValue.Resolution { if ( explicitMutabilityPlan != null ) { mutabilityPlan = explicitMutabilityPlan; } - else if ( domainJtd.getMutabilityPlan().isMutable() ) { - mutabilityPlan = new AttributeConverterMutabilityPlanImpl( converter, true ); + else if ( ! domainJtd.getMutabilityPlan().isMutable() ) { + mutabilityPlan = ImmutableMutabilityPlan.INSTANCE; } else { - mutabilityPlan = ImmutableMutabilityPlan.INSTANCE; + mutabilityPlan = new AttributeConverterMutabilityPlanImpl( converter, true ); } return new NamedConverterResolution( @@ -179,30 +179,34 @@ public class NamedConverterResolution implements BasicValue.Resolution { assert mutabilityPlan != null; this.mutabilityPlan = mutabilityPlan; - this.jdbcMapping = new JdbcMapping() { - private final ValueExtractor extractor = relationalStd.getExtractor( relationalJtd ); - private final ValueBinder binder = relationalStd.getBinder( relationalJtd ); - - @Override - public JavaTypeDescriptor getJavaTypeDescriptor() { - return relationalJtd; - } - - @Override - public SqlTypeDescriptor getSqlTypeDescriptor() { - return relationalStd; - } - - @Override - public ValueExtractor getJdbcValueExtractor() { - return extractor; - } - - @Override - public ValueBinder getJdbcValueBinder() { - return binder; - } - }; + this.jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve( + relationalJtd, + relationalStd + ); +// this.jdbcMapping = new JdbcMapping() { +// private final ValueExtractor extractor = relationalStd.getExtractor( relationalJtd ); +// private final ValueBinder binder = relationalStd.getBinder( relationalJtd ); +// +// @Override +// public JavaTypeDescriptor getJavaTypeDescriptor() { +// return relationalJtd; +// } +// +// @Override +// public SqlTypeDescriptor getSqlTypeDescriptor() { +// return relationalStd; +// } +// +// @Override +// public ValueExtractor getJdbcValueExtractor() { +// return extractor; +// } +// +// @Override +// public ValueBinder getJdbcValueBinder() { +// return binder; +// } +// }; // this.jdbcMapping = new ConverterJdbcMappingImpl( // domainJtd, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ConvertibleModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ConvertibleModelPart.java index ebbb8dc648..3c77e35b44 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ConvertibleModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ConvertibleModelPart.java @@ -11,7 +11,7 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; /** * @author Steve Ebersole */ -public interface ConvertibleModelPart extends ModelPart { +public interface ConvertibleModelPart extends BasicValuedModelPart { /** * Get the value converter applied to this model part if any */ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java index 39fcc7da3c..a6d54149b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java @@ -8,10 +8,14 @@ package org.hibernate.metamodel.model.convert.internal; import javax.persistence.AttributeConverter; +import org.hibernate.annotations.Immutable; import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter; import org.hibernate.resource.beans.spi.ManagedBean; +import org.hibernate.type.descriptor.converter.AttributeConverterMutabilityPlanImpl; +import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry; import org.hibernate.type.descriptor.java.spi.RegistryHelper; @@ -49,9 +53,26 @@ public class JpaAttributeConverterImpl implements JpaAttributeConverter) jtdRegistry.resolveDescriptor( domainJavaType, - () -> RegistryHelper.INSTANCE.createTypeDescriptor( domainJavaType, context.getTypeConfiguration() ) + () -> RegistryHelper.INSTANCE.createTypeDescriptor( + domainJavaType, + () -> { + final Class> converterClass = attributeConverterBean.getBeanClass(); + final MutabilityPlan mutabilityPlan = RegistryHelper.INSTANCE.determineMutabilityPlan( + converterClass, + context.getTypeConfiguration() + ); + + if ( mutabilityPlan != null ) { + return mutabilityPlan; + } + + return new AttributeConverterMutabilityPlanImpl<>( this, true ); + }, + context.getTypeConfiguration() + ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java index fe674ccec7..7f1ced56e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java @@ -168,11 +168,16 @@ public class QueryParameterBindingImpl implements QueryParameterBinding { bindValue( value ); - //noinspection unchecked - this.bindType = (AllowableParameterType) BindingTypeHelper.INSTANCE.resolveDateTemporalTypeVariant( - getBindType().getExpressableJavaTypeDescriptor().getJavaTypeClass(), - getBindType() - ); + if ( bindType == null ) { + bindType = queryParameter.getHibernateType(); + } + + if ( bindType != null ) { + bindType = (AllowableParameterType) BindingTypeHelper.INSTANCE.resolveDateTemporalTypeVariant( + bindType.getExpressableJavaTypeDescriptor().getJavaTypeClass(), + bindType + ); + } this.explicitTemporalPrecision = temporalTypePrecision; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java index d3ad73530e..9b5f93695f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java @@ -7,6 +7,7 @@ package org.hibernate.query.spi; import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.type.spi.TypeConfiguration; /** * A resolver for Type based on a parameter value being bound, when no @@ -17,4 +18,5 @@ import org.hibernate.metamodel.model.domain.AllowableParameterType; public interface QueryParameterBindingTypeResolver { AllowableParameterType resolveParameterBindType(Object bindValue); AllowableParameterType resolveParameterBindType(Class clazz); + TypeConfiguration getTypeConfiguration(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingValidator.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingValidator.java index 30cd6a54eb..6746b9759c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingValidator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingValidator.java @@ -11,7 +11,11 @@ import java.util.Collection; import java.util.Date; import javax.persistence.TemporalType; +import org.hibernate.metamodel.mapping.ConvertibleModelPart; +import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** * @author Andrea Boriero @@ -32,6 +36,16 @@ public class QueryParameterBindingValidator { // nothing we can check return; } + + if ( paramType instanceof AttributeConverterTypeAdapter ) { + final AttributeConverterTypeAdapter converterTypeAdapter = (AttributeConverterTypeAdapter) paramType; + final JavaTypeDescriptor domainJtd = converterTypeAdapter.getDomainJtd(); + + if ( domainJtd.getJavaTypeClass().isInstance( bind ) ) { + return; + } + } + final Class parameterType = paramType.getExpressableJavaTypeDescriptor().getJavaTypeClass(); if ( parameterType == null ) { // nothing we can check diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java index bf90334eb9..1782c958db 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java @@ -18,9 +18,12 @@ import java.util.function.Function; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.MappingMetamodel; +import org.hibernate.metamodel.mapping.ConvertibleModelPart; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; +import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; +import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.AllowableParameterType; import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.NavigablePath; @@ -39,6 +42,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.type.BasicType; +import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; import org.hibernate.type.spi.TypeConfiguration; /** @@ -176,7 +180,7 @@ public class SqmUtil { ); final Map>> jdbcParamMap = jdbcParamXref.get( queryParam ); - for ( SqmParameter sqmParameter : sqmParameters ) { + sqm_params: for ( SqmParameter sqmParameter : sqmParameters ) { final List> jdbcParamsBinds = jdbcParamMap.get( sqmParameter ); if ( !domainParamBinding.isBound() ) { final MappingModelExpressable mappingExpressable = SqmMappingModelHelper.resolveMappingModelExpressable( @@ -184,7 +188,7 @@ public class SqmUtil { domainModel, tableGroupLocator ); - for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) { + jdbc_params: for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) { final List jdbcParams = jdbcParamsBinds.get( i ); mappingExpressable.forEachJdbcType( (position, jdbcType) -> { @@ -246,6 +250,39 @@ public class SqmUtil { } } else { + if ( domainParamBinding.getType() instanceof AttributeConverterTypeAdapter + || domainParamBinding.getType() instanceof ConvertibleModelPart ) { + final BasicValueConverter valueConverter; + final JdbcMapping jdbcMapping; + + if ( domainParamBinding.getType() instanceof AttributeConverterTypeAdapter ) { + final AttributeConverterTypeAdapter adapter = (AttributeConverterTypeAdapter) domainParamBinding.getType(); + valueConverter = adapter.getAttributeConverter(); + jdbcMapping = adapter.getJdbcMapping(); + } + else { + final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) domainParamBinding.getType(); + valueConverter = convertibleModelPart.getValueConverter(); + jdbcMapping = convertibleModelPart.getJdbcMapping(); + } + + if ( valueConverter != null ) { + final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() ); + + for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) { + final List jdbcParams = jdbcParamsBinds.get( i ); + assert jdbcParams.size() == 1; + final JdbcParameter jdbcParameter = jdbcParams.get( 0 ); + jdbcParameterBindings.addBinding( + jdbcParameter, + new JdbcParameterBindingImpl( jdbcMapping, convertedValue ) + ); + } + + continue sqm_params; + } + } + final Object bindValue = domainParamBinding.getBindValue(); for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) { final List jdbcParams = jdbcParamsBinds.get( i ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 3bbf5014c5..98022df76c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -19,7 +19,6 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; - import javax.persistence.TemporalType; import org.hibernate.HibernateException; @@ -45,6 +44,7 @@ import org.hibernate.metamodel.mapping.Association; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.CollectionPart; +import org.hibernate.metamodel.mapping.ConvertibleModelPart; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EntityAssociationMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; @@ -57,6 +57,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.mapping.ordering.OrderByFragment; +import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType; import org.hibernate.metamodel.model.domain.AllowableParameterType; import org.hibernate.metamodel.model.domain.EntityDomainType; @@ -183,6 +184,7 @@ import org.hibernate.query.sqm.tree.update.SqmSetClause; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; +import org.hibernate.sql.ast.SqlTreeCreationException; import org.hibernate.sql.ast.SqlTreeCreationLogger; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlAliasBase; @@ -625,7 +627,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base popProcessingStateStack(); } - inferableTypeAccessStack.push( assignedPathInterpretation::getExpressionType ); + inferrableTypeAccessStack.push( assignedPathInterpretation::getExpressionType ); final List valueColumnReferences = new ArrayList<>(); pushProcessingState( @@ -703,7 +705,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base } finally { popProcessingStateStack(); - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } } @@ -2046,8 +2048,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public Expression visitLiteral(SqmLiteral literal) { + final Supplier inferableTypeAccess = inferrableTypeAccessStack.getCurrent(); + if ( literal instanceof SqmLiteralNull ) { - final MappingModelExpressable mappingModelExpressable = inferableTypeAccessStack.getCurrent().get(); + final MappingModelExpressable mappingModelExpressable = inferableTypeAccess.get(); if ( mappingModelExpressable instanceof BasicValuedMapping ) { return new NullnessLiteral( mappingModelExpressable ); } @@ -2063,14 +2067,52 @@ public abstract class BaseSqmToSqlAstConverter extends Base ); return new SqlTuple( expressions, mappingModelExpressable ); } - MappingModelExpressable expressable = SqmMappingModelHelper.resolveMappingModelExpressable( + + final MappingModelExpressable inferableExpressable = inferableTypeAccess.get(); + + if ( inferableExpressable instanceof ConvertibleModelPart ) { + final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) inferableExpressable; + final BasicValueConverter valueConverter = convertibleModelPart.getValueConverter(); + + if ( valueConverter != null ) { + final Object literalValue = literal.getLiteralValue(); + final Object sqlLiteralValue; + + if ( valueConverter.getDomainJavaDescriptor().getJavaTypeClass().isInstance( literalValue ) ) { + sqlLiteralValue = valueConverter.toRelationalValue( literalValue ); + } + else { + if ( !valueConverter.getRelationalJavaDescriptor().getJavaTypeClass().isInstance( literalValue ) ) { + throw new SqlTreeCreationException( + String.format( + Locale.ROOT, + "QueryLiteral type [`%s`] did not match domain Java-type [`%s`] nor JDBC Java-type [`%s`]", + literalValue.getClass(), + valueConverter.getDomainJavaDescriptor().getJavaTypeClass().getName(), + valueConverter.getRelationalJavaDescriptor().getJavaTypeClass().getName() + ) + ); + } + sqlLiteralValue = literalValue; + } + + return new QueryLiteral<>( sqlLiteralValue, (BasicValuedMapping) inferableExpressable ); + } + } + + final MappingModelExpressable expressable; + final MappingModelExpressable localExpressable = SqmMappingModelHelper.resolveMappingModelExpressable( literal, getCreationContext().getDomainModel(), getFromClauseAccess()::findTableGroup ); - if ( expressable instanceof BasicType ) { - expressable = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType) expressable ); + if ( localExpressable instanceof BasicType ) { + expressable = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType) localExpressable ); } + else { + expressable = localExpressable; + } + return new QueryLiteral<>( literal.getLiteralValue(), (BasicValuedMapping) expressable @@ -2131,7 +2173,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base nodeType ); if ( valueMapping == null ) { - final Supplier currentExpressableSupplier = inferableTypeAccessStack.getCurrent(); + final Supplier currentExpressableSupplier = inferrableTypeAccessStack.getCurrent(); if ( currentExpressableSupplier != null ) { return currentExpressableSupplier.get(); } @@ -2149,30 +2191,62 @@ public abstract class BaseSqmToSqlAstConverter extends Base return determineValueMapping( (SqmParameter) sqmExpression ); } + final MappingMetamodel domainModel = getCreationContext().getDomainModel(); if ( sqmExpression instanceof SqmPath ) { log.debugf( "Determining mapping-model type for SqmPath : %s ", sqmExpression ); return SqmMappingModelHelper.resolveMappingModelExpressable( sqmExpression, - getCreationContext().getDomainModel(), + domainModel, getFromClauseAccess()::findTableGroup ); } // The model type of an enum literal is always inferred if ( sqmExpression instanceof SqmEnumLiteral ) { - final Supplier currentExpressableSupplier = inferableTypeAccessStack.getCurrent(); + final Supplier currentExpressableSupplier = inferrableTypeAccessStack.getCurrent(); if ( currentExpressableSupplier != null ) { return currentExpressableSupplier.get(); } } + if ( sqmExpression instanceof SqmSubQuery ) { + final SqmSubQuery subQuery = (SqmSubQuery) sqmExpression; + final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause(); + if ( selectClause.getSelections().size() == 1 ) { + final SqmSelection subQuerySelection = selectClause.getSelections().get( 0 ); + final SqmExpressable selectionNodeType = subQuerySelection.getNodeType(); + if ( selectionNodeType != null ) { + final SqmExpressable sqmExpressable; + if ( selectionNodeType instanceof PluralPersistentAttribute ) { + sqmExpressable = ( (PluralPersistentAttribute) selectionNodeType ).getElementPathSource(); + } + else { + sqmExpressable = selectionNodeType; + } + + final MappingModelExpressable expressable = domainModel.resolveMappingExpressable( sqmExpressable ); + + if ( expressable != null ) { + return expressable; + } + + try { + return inferrableTypeAccessStack.getCurrent().get(); + } + catch (Exception ignore) { + return null; + } + } + } + } + log.debugf( "Determining mapping-model type for generalized SqmExpression : %s", sqmExpression ); final SqmExpressable nodeType = sqmExpression.getNodeType(); - final MappingModelExpressable valueMapping = getCreationContext().getDomainModel().resolveMappingExpressable( + final MappingModelExpressable valueMapping = domainModel.resolveMappingExpressable( nodeType ); if ( valueMapping == null ) { - final Supplier currentExpressableSupplier = inferableTypeAccessStack.getCurrent(); + final Supplier currentExpressableSupplier = inferrableTypeAccessStack.getCurrent(); if ( currentExpressableSupplier != null ) { return currentExpressableSupplier.get(); } @@ -2196,7 +2270,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base // this should indicate the condition that the user query did not define an // explicit type in regard to this parameter. Here we should prefer the // inferable type and fallback to the binding type - final Supplier currentExpressableSupplier = inferableTypeAccessStack.getCurrent(); + final Supplier currentExpressableSupplier = inferrableTypeAccessStack.getCurrent(); if ( currentExpressableSupplier != null ) { final MappingModelExpressable inferredMapping = currentExpressableSupplier.get(); if ( inferredMapping != null ) { @@ -2226,7 +2300,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base throw new ConversionException( "Could not determine ValueMapping for SqmParameter: " + sqmParameter ); } - protected final Stack> inferableTypeAccessStack = new StandardStack<>( + protected final Stack> inferrableTypeAccessStack = new StandardStack<>( () -> null ); @@ -2286,12 +2360,12 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public Expression visitFunction(SqmFunction sqmFunction) { - inferableTypeAccessStack.push( () -> null ); + inferrableTypeAccessStack.push( () -> null ); try { return sqmFunction.convertToSqlAst( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } } @@ -3242,6 +3316,14 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) { + final BasicValuedMapping inferrableType = (BasicValuedMapping) inferrableTypeAccessStack.getCurrent().get(); + if ( inferrableType instanceof ConvertibleModelPart ) { + final ConvertibleModelPart inferredPart = (ConvertibleModelPart) inferrableType; + final BasicValueConverter valueConverter = inferredPart.getValueConverter(); + final Object jdbcValue = valueConverter.toRelationalValue( sqmEnumLiteral.getEnumValue() ); + return new QueryLiteral<>( jdbcValue, inferredPart ); + } + return new QueryLiteral<>( sqmEnumLiteral.getEnumValue(), (BasicValuedMapping) determineValueMapping( sqmEnumLiteral ) @@ -3316,15 +3398,15 @@ public abstract class BaseSqmToSqlAstConverter extends Base pluralPath ); if ( mappingModelExpressable.getElementDescriptor() instanceof EntityCollectionPart ) { - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> ( (EntityCollectionPart) mappingModelExpressable.getElementDescriptor() ).getKeyTargetMatchPart() ); } else if ( mappingModelExpressable.getElementDescriptor() instanceof EmbeddedCollectionPart ) { - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> mappingModelExpressable.getElementDescriptor() ); } else { - inferableTypeAccessStack.push( () -> mappingModelExpressable ); + inferrableTypeAccessStack.push( () -> mappingModelExpressable ); } final Expression lhs; @@ -3332,7 +3414,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base lhs = (Expression) predicate.getLeftHandExpression().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return new InSubQueryPredicate( @@ -3403,24 +3485,24 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public ComparisonPredicate visitComparisonPredicate(SqmComparisonPredicate predicate) { - inferableTypeAccessStack.push( () -> determineValueMapping( predicate.getRightHandExpression() ) ); + inferrableTypeAccessStack.push( () -> determineValueMapping( predicate.getRightHandExpression() ) ); final Expression lhs; try { lhs = (Expression) predicate.getLeftHandExpression().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } - inferableTypeAccessStack.push( () -> determineValueMapping( predicate.getLeftHandExpression() ) ); + inferrableTypeAccessStack.push( () -> determineValueMapping( predicate.getLeftHandExpression() ) ); final Expression rhs; try { rhs = (Expression) predicate.getRightHandExpression().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return new ComparisonPredicate( lhs, predicate.getSqmOperator(), rhs ); @@ -3497,7 +3579,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base final Expression lowerBound; final Expression upperBound; - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> coalesceSuppliedValues( () -> determineValueMapping( predicate.getLowerBound() ), () -> determineValueMapping( predicate.getUpperBound() ) @@ -3508,10 +3590,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base expression = (Expression) predicate.getExpression().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> coalesceSuppliedValues( () -> determineValueMapping( predicate.getExpression() ), () -> determineValueMapping( predicate.getUpperBound() ) @@ -3521,10 +3603,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base lowerBound = (Expression) predicate.getLowerBound().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> coalesceSuppliedValues( () -> determineValueMapping( predicate.getExpression() ), () -> determineValueMapping( predicate.getLowerBound() ) @@ -3534,7 +3616,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base upperBound = (Expression) predicate.getUpperBound().accept( this ); } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return new BetweenPredicate( @@ -3593,7 +3675,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base predicate.isNegated() ); - inferableTypeAccessStack.push( () -> determineValueMapping( predicate.getTestExpression() ) ); + inferrableTypeAccessStack.push( () -> determineValueMapping( predicate.getTestExpression() ) ); try { for ( SqmExpression expression : predicate.getListExpressions() ) { @@ -3601,7 +3683,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base } } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return inPredicate; @@ -3632,7 +3714,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base (Expression) sqmPredicate.getTestExpression().accept( this ) ); - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> determineValueMapping( sqmPredicate.getTestExpression() ) ); @@ -3654,7 +3736,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base } } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return inListPredicate; @@ -3674,7 +3756,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base (Expression) sqmPredicate.getTestExpression().accept( this ) ); - inferableTypeAccessStack.push( + inferrableTypeAccessStack.push( () -> determineValueMapping( sqmPredicate.getTestExpression() ) ); @@ -3699,7 +3781,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base } } finally { - inferableTypeAccessStack.pop(); + inferrableTypeAccessStack.pop(); } return inListPredicate; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 7a1edcf494..4d63c20d43 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -487,6 +487,7 @@ public abstract class AbstractSqlAstTranslator implemen else { throw new IllegalArgumentException( "Unexpected statement!" ); } + if ( jdbcParameterBindings != null && CollectionHelper.isNotEmpty( getFilterJdbcParameters() ) ) { for ( FilterJdbcParameter filterJdbcParameter : getFilterJdbcParameters() ) { jdbcParameterBindings.addBinding( @@ -495,6 +496,7 @@ public abstract class AbstractSqlAstTranslator implemen ); } } + return (T) jdbcOperation; } finally { @@ -2437,9 +2439,12 @@ public abstract class AbstractSqlAstTranslator implemen @SuppressWarnings("unchecked") protected void renderLiteral(Literal literal, boolean castParameter) { assert literal.getExpressionType().getJdbcTypeCount() == 1; + final JdbcMapping jdbcMapping = literal.getJdbcMapping(); - final JdbcLiteralFormatter literalFormatter = jdbcMapping.getSqlTypeDescriptor() + final JdbcLiteralFormatter literalFormatter = jdbcMapping + .getSqlTypeDescriptor() .getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() ); + // If we encounter a plain literal in the select clause which has no literal formatter, we must render it as parameter if ( literalFormatter == null ) { parameterBinders.add( literal ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java index 91cd103ba1..b870b247c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java @@ -35,16 +35,8 @@ public class QueryLiteral implements Literal, DomainResultProducer { private final BasicValuedMapping type; public QueryLiteral(T value, BasicValuedMapping type) { + this.value = value; this.type = type; - - if ( type instanceof ConvertibleModelPart ) { - final ConvertibleModelPart convertible = (ConvertibleModelPart) type; - final BasicValueConverter valueConverter = convertible.getValueConverter(); - this.value = (T) valueConverter.toRelationalValue( value ); - } - else { - this.value = value; - } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java index 558f982f38..748acd9000 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java @@ -224,7 +224,7 @@ public abstract class AbstractStandardBasicType @Override @SuppressWarnings({ "unchecked" }) - public final boolean isEqual(Object one, Object another) { + public boolean isEqual(Object one, Object another) { return javaTypeDescriptor.areEqual( (T) one, (T) another ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java index 8dd3636c0d..5f0a6342e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java @@ -372,10 +372,21 @@ public class TypeHelper { int span = properties.length; for ( int i = 0; i < span; i++ ) { - final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY && - ( previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || - ( properties[i].isDirtyCheckable() - && properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session ) ) ); + final boolean dirty; + if ( currentState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { + dirty = false; + } + else if ( previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { + dirty = true; + } + else if ( properties[i].isDirtyCheckable() + && properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session ) ) { + dirty = true; + } + else { + dirty = false; + } + if ( dirty ) { if ( results == null ) { results = new int[span]; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java index 3ee98b37a4..239563b517 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import javax.persistence.AttributeConverter; +import org.hibernate.HibernateException; import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter; @@ -116,6 +117,12 @@ public class AttributeConverterTypeAdapter extends AbstractSingleColumnStanda return mutabilityPlan; } + @Override + public boolean isEqual(Object one, Object another) { + //noinspection unchecked + return ( (JavaTypeDescriptor) getDomainJtd() ).areEqual( one, another ); + } + @Override public String toString() { return description; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorBaseline.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorBaseline.java index 912ec91196..bfbf98629d 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorBaseline.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorBaseline.java @@ -48,6 +48,7 @@ import org.hibernate.type.descriptor.java.DurationJavaDescriptor; import org.hibernate.type.descriptor.java.FloatTypeDescriptor; import org.hibernate.type.descriptor.java.InstantJavaDescriptor; import org.hibernate.type.descriptor.java.IntegerTypeDescriptor; +import org.hibernate.type.descriptor.java.JavaObjectTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JdbcDateTypeDescriptor; import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor; @@ -88,6 +89,8 @@ public class JavaTypeDescriptorBaseline { primePrimitive( target, FloatTypeDescriptor.INSTANCE ); primePrimitive( target, DoubleTypeDescriptor.INSTANCE ); + target.addBaselineDescriptor( JavaObjectTypeDescriptor.INSTANCE ); + target.addBaselineDescriptor( BigDecimalTypeDescriptor.INSTANCE ); target.addBaselineDescriptor( BigIntegerTypeDescriptor.INSTANCE ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java index 12196dea23..e11a3990ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java @@ -12,17 +12,9 @@ import java.lang.reflect.Type; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -import org.hibernate.annotations.Immutable; -import org.hibernate.annotations.Mutability; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -import org.hibernate.resource.beans.spi.ManagedBean; -import org.hibernate.resource.beans.spi.ManagedBeanRegistry; -import org.hibernate.type.descriptor.java.AbstractClassTypeDescriptor; -import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; -import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.MutabilityPlan; -import org.hibernate.type.descriptor.java.SerializableTypeDescriptor; +import org.hibernate.type.descriptor.java.MutableMutabilityPlan; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfigurationAware; @@ -132,7 +124,6 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba return created; } - @SuppressWarnings("unchecked") public JavaTypeDescriptor resolveDescriptor(Type javaType) { return resolveDescriptor( javaType, @@ -148,6 +139,20 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba return RegistryHelper.INSTANCE.createTypeDescriptor( javaTypeClass, + () -> { + final MutabilityPlan determinedPlan = RegistryHelper.INSTANCE.determineMutabilityPlan( javaType, typeConfiguration ); + if ( determinedPlan != null ) { + return determinedPlan; + } + + return new MutableMutabilityPlan() { + @Override + protected J deepCopyNotNull(J value) { + return value; + } + }; + + }, typeConfiguration ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java index 5979072f6c..3fce115f88 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java @@ -10,6 +10,7 @@ import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.function.Function; +import java.util.function.Supplier; import org.hibernate.annotations.Immutable; import org.hibernate.annotations.Mutability; @@ -35,42 +36,60 @@ public class RegistryHelper { private RegistryHelper() { } - @SuppressWarnings("unchecked") - public JavaTypeDescriptor createTypeDescriptor(Type javaType, TypeConfiguration typeConfiguration) { + public JavaTypeDescriptor createTypeDescriptor( + Type javaType, + Supplier> fallbackMutabilityPlanResolver, + TypeConfiguration typeConfiguration) { return createTypeDescriptor( javaType, (javaTypeClass) -> { - if ( javaTypeClass.isAnnotationPresent( Immutable.class ) ) { - return ImmutableMutabilityPlan.INSTANCE; + MutabilityPlan mutabilityPlan = determineMutabilityPlan( javaType, typeConfiguration ); + if ( mutabilityPlan == null ) { + mutabilityPlan = fallbackMutabilityPlanResolver.get(); } - - if ( javaTypeClass.isAnnotationPresent( Mutability.class ) ) { - final Mutability annotation = javaTypeClass.getAnnotation( Mutability.class ); - final Class> planClass = annotation.value(); - final ManagedBeanRegistry managedBeanRegistry = typeConfiguration - .getServiceRegistry() - .getService( ManagedBeanRegistry.class ); - final ManagedBean> planBean = managedBeanRegistry.getBean( planClass ); - return (MutabilityPlan) planBean.getBeanInstance(); - } - - return ImmutableMutabilityPlan.INSTANCE; + return mutabilityPlan; } ); } @SuppressWarnings("unchecked") - public JavaTypeDescriptor createTypeDescriptor( + public MutabilityPlan determineMutabilityPlan(Type javaType, TypeConfiguration typeConfiguration) { + final Class javaTypeClass = determineJavaTypeClass( javaType ); + + if ( javaTypeClass.isAnnotationPresent( Immutable.class ) ) { + return ImmutableMutabilityPlan.INSTANCE; + } + + if ( javaTypeClass.isAnnotationPresent( Mutability.class ) ) { + final Mutability annotation = javaTypeClass.getAnnotation( Mutability.class ); + final Class> planClass = annotation.value(); + final ManagedBeanRegistry managedBeanRegistry = typeConfiguration + .getServiceRegistry() + .getService( ManagedBeanRegistry.class ); + final ManagedBean> planBean = managedBeanRegistry.getBean( planClass ); + return (MutabilityPlan) planBean.getBeanInstance(); + } + + if ( javaTypeClass.isEnum() ) { + return ImmutableMutabilityPlan.INSTANCE; + } + + if ( javaTypeClass.isPrimitive() ) { + return ImmutableMutabilityPlan.INSTANCE; + } + + if ( Serializable.class.isAssignableFrom( javaTypeClass ) ) { + return (MutabilityPlan) SerializableTypeDescriptor.SerializableMutabilityPlan.INSTANCE; + } + + return null; + } + + @SuppressWarnings("unchecked") + private JavaTypeDescriptor createTypeDescriptor( Type javaType, Function,MutabilityPlan> mutabilityPlanResolver) { - final Class javaTypeClass; - if ( javaType instanceof Class ) { - javaTypeClass = (Class) javaType; - } - else { - final ParameterizedType parameterizedType = (ParameterizedType) javaType; - javaTypeClass = (Class) parameterizedType.getRawType(); - } + final Class javaTypeClass = determineJavaTypeClass( javaType ); if ( javaTypeClass.isEnum() ) { // enums are unequivocally immutable @@ -87,4 +106,16 @@ public class RegistryHelper { return new JavaTypeDescriptorBasicAdaptor<>( javaTypeClass, plan ); } + + private Class determineJavaTypeClass(Type javaType) { + final Class javaTypeClass; + if ( javaType instanceof Class ) { + javaTypeClass = (Class) javaType; + } + else { + final ParameterizedType parameterizedType = (ParameterizedType) javaType; + javaTypeClass = (Class) parameterizedType.getRawType(); + } + return javaTypeClass; + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/AndLobTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndLobTest.java similarity index 53% rename from hibernate-core/src/test/java/org/hibernate/test/converter/AndLobTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndLobTest.java index e444829379..ca74c9af9b 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/AndLobTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndLobTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.sql.Types; import javax.persistence.AttributeConverter; @@ -16,21 +16,19 @@ import javax.persistence.Lob; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.dialect.Dialect; import org.hibernate.type.Type; import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; import org.hibernate.testing.junit4.BaseUnitTestCase; -import org.hibernate.type.descriptor.sql.BlobTypeDescriptor; -import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.ServiceRegistryScope; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; /** * Test mapping a model with an attribute combining {@code @Lob} with an AttributeConverter. @@ -39,31 +37,20 @@ import static org.junit.Assert.assertEquals; * * @author Steve Ebersole */ -public class AndLobTest extends BaseUnitTestCase { - private StandardServiceRegistry ssr; - - @Before - public void before() { - ssr = new StandardServiceRegistryBuilder().build(); - } - - @After - public void after() { - if ( ssr != null ) { - StandardServiceRegistryBuilder.destroy( ssr ); - } - } - +@ServiceRegistry +public class AndLobTest { @Test - public void testMappingAttributeWithLobAndAttributeConverter() { - final Metadata metadata = new MetadataSources( ssr ) + public void testMappingAttributeWithLobAndAttributeConverter(ServiceRegistryScope scope) { + final Metadata metadata = new MetadataSources( scope.getRegistry() ) .addAnnotatedClass( EntityImpl.class ) .buildMetadata(); final Type type = metadata.getEntityBinding( EntityImpl.class.getName() ).getProperty( "status" ).getType(); - final AttributeConverterTypeAdapter concreteType = assertTyping( AttributeConverterTypeAdapter.class, type ); - SqlTypeDescriptor sqlTypeDescriptor = concreteType.getSqlTypeDescriptor(); - assertEquals( Dialect.getDialect().remapSqlTypeDescriptor(BlobTypeDescriptor.BLOB_BINDING).getSqlType(), sqlTypeDescriptor.getSqlType() ); + final AttributeConverterTypeAdapter typeAdapter = assertTyping( AttributeConverterTypeAdapter.class, type ); + + assertThat( typeAdapter.getDomainJtd().getJavaTypeClass(), equalTo( String.class ) ); + assertThat( typeAdapter.getRelationalJtd().getJavaTypeClass(), equalTo( Integer.class ) ); + assertThat( typeAdapter.getSqlTypeDescriptor().getJdbcTypeCode(), is( Types.INTEGER ) ); } @Converter diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/AndNationalizedTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/AndNationalizedTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java index 029b174f62..c7c559b773 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/AndNationalizedTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.sql.Types; import javax.persistence.AttributeConverter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/AttributeConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AttributeConverterTest.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/test/converter/AttributeConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AttributeConverterTest.java index ac00016dcf..147ee4e58c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/AttributeConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AttributeConverterTest.java @@ -1,15 +1,15 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; -import java.io.Serializable; import java.sql.Clob; import java.sql.Timestamp; import java.sql.Types; +import java.time.Instant; import javax.persistence.AttributeConverter; import javax.persistence.Column; import javax.persistence.Convert; @@ -18,7 +18,6 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import org.hibernate.AnnotationException; import org.hibernate.IrrelevantEntity; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -30,22 +29,21 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; -import org.hibernate.dialect.Dialect; import org.hibernate.dialect.HANAColumnStoreDialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.ConfigHelper; import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.SimpleValue; +import org.hibernate.resource.beans.spi.ManagedBean; +import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.type.AbstractStandardBasicType; import org.hibernate.type.Type; import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; -import org.hibernate.type.descriptor.java.IntegerTypeDescriptor; import org.hibernate.type.descriptor.java.StringTypeDescriptor; -import org.hibernate.type.descriptor.sql.ClobTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; -import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl; @@ -76,9 +74,16 @@ public class AttributeConverterTest extends BaseUnitTestCase { Configuration cfg = new Configuration(); try { cfg.addAttributeConverter( BlowsUpConverter.class ); - fail( "expecting an exception" ); + try ( final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) cfg.buildSessionFactory() ) { + final ManagedBeanRegistry managedBeanRegistry = sessionFactory + .getServiceRegistry() + .getService( ManagedBeanRegistry.class ); + final ManagedBean converterBean = managedBeanRegistry.getBean( BlowsUpConverter.class ); + converterBean.getBeanInstance(); + fail( "expecting an exception" ); + } } - catch (AnnotationException e) { + catch (Exception e) { assertTyping( BlewUpException.class, ExceptionUtil.rootCause( e ) ); } } @@ -291,24 +296,24 @@ public class AttributeConverterTest extends BaseUnitTestCase { final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build(); try { - MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) + final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Tester5.class ) .getMetadataBuilder() .applyAttributeConverter( IntegerToVarcharConverter.class, true ) .build(); - PersistentClass tester = metadata.getEntityBinding( Tester5.class.getName() ); - Property codeProp = tester.getProperty( "code" ); - SimpleValue nameValue = (SimpleValue) codeProp.getValue(); + final PersistentClass tester = metadata.getEntityBinding( Tester5.class.getName() ); + final Property codeProp = tester.getProperty( "code" ); + final BasicValue nameValue = (BasicValue) codeProp.getValue(); Type type = nameValue.getType(); assertNotNull( type ); - if ( !AttributeConverterTypeAdapter.class.isInstance( type ) ) { - fail( "AttributeConverter not applied to primitive type field: code(int)" ); - } - AttributeConverterTypeAdapter basicType = assertTyping( AttributeConverterTypeAdapter.class, type ); - assertSame( IntegerTypeDescriptor.INSTANCE, basicType.getJavaTypeDescriptor() ); - SqlTypeDescriptor sqlTypeDescriptor = basicType.getSqlTypeDescriptor(); - assertEquals( VarcharTypeDescriptor.INSTANCE.getSqlType(), sqlTypeDescriptor.getSqlType() ); + assertThat( type, instanceOf( AttributeConverterTypeAdapter.class ) ); + + final AttributeConverterTypeAdapter typeAdapter = (AttributeConverterTypeAdapter) type; + + assertThat( typeAdapter.getDomainJtd().getJavaTypeClass(), equalTo( Integer.class ) ); + assertThat( typeAdapter.getRelationalJtd().getJavaTypeClass(), equalTo( String.class ) ); + assertThat( typeAdapter.getSqlTypeDescriptor().getJdbcTypeCode(), is( Types.VARCHAR ) ); } finally { StandardServiceRegistryBuilder.destroy( ssr ); @@ -454,7 +459,7 @@ public class AttributeConverterTest extends BaseUnitTestCase { s = sf.openSession(); s.beginTransaction(); - s.createQuery( "FROM EntityWithConvertibleField e where e.convertibleEnum = org.hibernate.test.converter.AttributeConverterTest$ConvertibleEnum.VALUE" ) + s.createQuery( "FROM EntityWithConvertibleField e where e.convertibleEnum = org.hibernate.orm.test.mapping.converted.converter.AttributeConverterTest$ConvertibleEnum.VALUE" ) .list(); s.getTransaction().commit(); s.close(); @@ -563,29 +568,6 @@ public class AttributeConverterTest extends BaseUnitTestCase { } } - // This class is for mimicking an Instant from Java 8, which a converter might convert to a java.sql.Timestamp - public static class Instant implements Serializable { - private static final long serialVersionUID = 1L; - - private long javaMillis; - - public Instant(long javaMillis) { - this.javaMillis = javaMillis; - } - - public long toJavaMillis() { - return javaMillis; - } - - public static Instant fromJavaMillis(long javaMillis) { - return new Instant( javaMillis ); - } - - public static Instant now() { - return new Instant( System.currentTimeMillis() ); - } - } - @Entity @Table(name = "irrelevantInstantEntity") @SuppressWarnings("UnusedDeclaration") @@ -713,12 +695,12 @@ public class AttributeConverterTest extends BaseUnitTestCase { public static class InstantConverter implements AttributeConverter { @Override public Timestamp convertToDatabaseColumn(Instant attribute) { - return new Timestamp( attribute.toJavaMillis() ); + return new Timestamp( attribute.getEpochSecond() ); } @Override public Instant convertToEntityAttribute(Timestamp dbData) { - return Instant.fromJavaMillis( dbData.getTime() ); + return Instant.ofEpochSecond( dbData.getTime() ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/BasicJodaTimeConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/BasicJodaTimeConversionTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/BasicJodaTimeConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/BasicJodaTimeConversionTest.java index 09bafcb499..045473fc30 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/BasicJodaTimeConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/BasicJodaTimeConversionTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import java.util.Date; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ConvertedAttributeUsageTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConvertedAttributeUsageTests.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ConvertedAttributeUsageTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConvertedAttributeUsageTests.java index a408623896..e1887debf9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ConvertedAttributeUsageTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConvertedAttributeUsageTests.java @@ -4,7 +4,7 @@ * 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.orm.test.mapping.converted; +package org.hibernate.orm.test.mapping.converted.converter; import org.hibernate.testing.orm.domain.gambit.EntityOfBasics; import org.hibernate.testing.orm.domain.gambit.MutableValue; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/ConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConverterTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/converter/ConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConverterTest.java index 6adda87e0c..fed1a44024 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/ConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ConverterTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Convert; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/DirtyCheckingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/DirtyCheckingTest.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/test/converter/DirtyCheckingTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/DirtyCheckingTest.java index a38639e14b..7e2879dda6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/DirtyCheckingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/DirtyCheckingTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Column; @@ -14,6 +14,7 @@ import javax.persistence.Id; import org.hibernate.Session; +import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.junit.Test; @@ -115,6 +116,9 @@ public class DirtyCheckingTest extends BaseNonConfigCoreFunctionalTestCase { @Test public void checkConverterMutabilityPlans() { final EntityPersister persister = sessionFactory().getEntityPersister( SomeEntity.class.getName() ); + final AttributeMapping numberMapping = persister.findAttributeMapping( "number" ); + final AttributeMapping nameMapping = persister.findAttributeMapping( "name" ); + assertFalse( persister.getPropertyType( "number" ).isMutable() ); assertTrue( persister.getPropertyType( "name" ).isMutable() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitDateConvertersTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitDateConvertersTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitDateConvertersTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitDateConvertersTest.java index 24928ba4e5..a638cc3e5f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitDateConvertersTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitDateConvertersTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import java.util.Date; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitEnumConvertersTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitEnumConvertersTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitEnumConvertersTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitEnumConvertersTest.java index 2300a270c3..9627cf70c4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitEnumConvertersTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitEnumConvertersTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import javax.persistence.AttributeConverter; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ExplicitJavaTypeDescriptorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitJavaTypeDescriptorTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ExplicitJavaTypeDescriptorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitJavaTypeDescriptorTest.java index 392385eb50..019e6ea609 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/ExplicitJavaTypeDescriptorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitJavaTypeDescriptorTest.java @@ -4,7 +4,7 @@ * 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.orm.test.mapping.converted; +package org.hibernate.orm.test.mapping.converted.converter; import java.sql.Types; import java.util.Locale; @@ -56,7 +56,6 @@ public class ExplicitJavaTypeDescriptorTest extends BaseNonConfigCoreFunctionalT @Test @TestForIssue( jiraKey = "HHH-11098" ) - @FailureExpected( jiraKey = "n/a", message = "Arg!!!" ) public void testIt() { // create data and check assertions inTransaction( diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitlyNamedConverterClassesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitlyNamedConverterClassesTest.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitlyNamedConverterClassesTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitlyNamedConverterClassesTest.java index a4572d18ce..e98bb7b232 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/ExplicitlyNamedConverterClassesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/ExplicitlyNamedConverterClassesTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Converter; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/LongToDateConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/LongToDateConversionTest.java new file mode 100644 index 0000000000..543dd5b591 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/LongToDateConversionTest.java @@ -0,0 +1,121 @@ +/* + * 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.orm.test.mapping.converted.converter; + +import java.io.Serializable; +import java.util.Date; +import java.util.stream.Stream; +import javax.persistence.AttributeConverter; +import javax.persistence.Column; +import javax.persistence.Convert; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TemporalType; + +import org.hibernate.query.Query; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * @author Andrea Boriero + */ +@TestForIssue(jiraKey = "HHH-10959") +@DomainModel( annotatedClasses = LongToDateConversionTest.TestEntity.class ) +@SessionFactory +public class LongToDateConversionTest { + + @Test + public void testSetParameter(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + final String qryStr = "SELECT e FROM TestEntity e WHERE e.date <= :ts"; + final Query query = session.createQuery( qryStr, TestEntity.class ); + query.setParameter( "ts", new DateAttribute( System.currentTimeMillis() ), TemporalType.TIMESTAMP ); + final Stream stream = query.stream(); + assertThat( stream.count(), is( 1L ) ); + } + ); + } + + @BeforeEach + public void createTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + TestEntity entity = new TestEntity(); + entity.setDate( new DateAttribute( System.currentTimeMillis() ) ); + session.persist( entity ); + } + ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete TestEntity" ).executeUpdate() + ); + } + + @Entity(name = "TestEntity") + @Table(name = "TEST_ENTITY") + public static class TestEntity { + + @Id + @GeneratedValue + private long id; + + @Convert(converter = DateAttributeConverter.class) + @Column(name = "attribute_date") + private DateAttribute date; + + public DateAttribute getDate() { + return date; + } + + public void setDate(DateAttribute date) { + this.date = date; + } + } + + public static class DateAttribute implements Serializable { + private long field; + + public DateAttribute(long field) { + this.field = field; + } + } + + public static class DateAttributeConverter implements AttributeConverter { + + @Override + public Date convertToDatabaseColumn(DateAttribute attribute) { + if ( attribute == null ) { + return null; + } + return new Date( attribute.field ); + } + + @Override + public DateAttribute convertToEntityAttribute(Date dbData) { + if ( dbData == null ) { + return null; + } + return new DateAttribute( dbData.getTime() ); + } + + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/NullHandlingTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/NullHandlingTests.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/converter/NullHandlingTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/NullHandlingTests.java index 1f378f1f89..7cd34d6789 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/NullHandlingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/NullHandlingTests.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.sql.Connection; import java.sql.ResultSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java index c3b8bb6028..9901f819b1 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterEntityManagerFactoryTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Convert; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterSessionFactoryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterSessionFactoryTest.java similarity index 53% rename from hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterSessionFactoryTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterSessionFactoryTest.java index 60ce33fcbc..246e073301 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/PackagePrivateAttributeConverterSessionFactoryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/PackagePrivateAttributeConverterSessionFactoryTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Convert; @@ -14,47 +14,49 @@ import javax.persistence.Id; import javax.persistence.Tuple; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.NotImplementedYet; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertEquals; /** * @author Vlad Mihalcea */ @TestForIssue( jiraKey = "HHH-10778" ) -public class PackagePrivateAttributeConverterSessionFactoryTest extends BaseNonConfigCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Tester.class }; - } +@DomainModel( annotatedClasses = PackagePrivateAttributeConverterSessionFactoryTest.Tester.class ) +@SessionFactory +public class PackagePrivateAttributeConverterSessionFactoryTest { @Test - public void test() { - doInHibernate( this::sessionFactory, session -> { - Tester tester = new Tester(); - tester.setId( 1L ); - tester.setCode( 123 ); + @NotImplementedYet( strict = false, reason = "Support for creating native-query with result-type not implemented" ) + public void test(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Tester tester = new Tester(); + tester.setId( 1L ); + tester.setCode( 123 ); - session.persist( tester ); - } ); + session.persist( tester ); + } + ); - doInHibernate( this::sessionFactory, session -> { - Tuple tuple = session.createNativeQuery( - "select code " + - "from Tester " + - "where id = :id", Tuple.class ) - .setParameter( "id", 1L ) - .getSingleResult(); + scope.inTransaction( + (session) -> { + Tuple tuple = (Tuple) session.createNativeQuery( + "select code " + + "from Tester " + + "where id = :id", Tuple.class ) + .setParameter( "id", 1L ) + .getSingleResult(); + assertEquals( "123", tuple.get( "code" ) ); - assertEquals( "123", tuple.get( "code" ) ); - - Tester tester = session.find( Tester.class, 1L ); - - assertEquals( 123, (int) tester.getCode() ); - } ); + Tester tester = session.find( Tester.class, 1L ); + assertEquals( 123, (int) tester.getCode() ); + } + ); } // Entity declarations used in the test ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/QueryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/QueryTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/converter/QueryTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/QueryTest.java index ed29ad5330..8c5c80b4e6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/QueryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/QueryTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Column; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SillyStringConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SillyStringConverter.java similarity index 76% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SillyStringConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SillyStringConverter.java index 1a35b93c5a..51b3efa434 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SillyStringConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SillyStringConverter.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.AttributeConverter; import javax.persistence.Converter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertAnnotationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertAnnotationTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertAnnotationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertAnnotationTest.java index c2e34e4a4d..ff0ebc1ea3 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertAnnotationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertAnnotationTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import java.net.URL; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertsAnnotationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertsAnnotationTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertsAnnotationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertsAnnotationTest.java index 379e9bd823..c630555b96 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleConvertsAnnotationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleConvertsAnnotationTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import java.net.URL; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleEmbeddableOverriddenConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleEmbeddableOverriddenConverterTest.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SimpleEmbeddableOverriddenConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleEmbeddableOverriddenConverterTest.java index 3199cf3d1c..3df4800007 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleEmbeddableOverriddenConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleEmbeddableOverriddenConverterTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.Convert; import javax.persistence.Embeddable; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleOverriddenConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleOverriddenConverterTest.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SimpleOverriddenConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleOverriddenConverterTest.java index ba71f73222..14fa93337f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleOverriddenConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleOverriddenConverterTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.Convert; import javax.persistence.Entity; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleXmlOverriddenTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleXmlOverriddenTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/SimpleXmlOverriddenTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleXmlOverriddenTest.java index cf9869d968..9902f4fa54 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/SimpleXmlOverriddenTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/SimpleXmlOverriddenTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import javax.persistence.Convert; import javax.persistence.Entity; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/StringClobConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/StringClobConverter.java similarity index 77% rename from hibernate-core/src/test/java/org/hibernate/test/converter/StringClobConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/StringClobConverter.java index 59c9b5f524..b1138b46c1 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/StringClobConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/StringClobConverter.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.sql.Clob; import javax.persistence.AttributeConverter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/XmlWithExplicitConvertAnnotationsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/XmlWithExplicitConvertAnnotationsTest.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/XmlWithExplicitConvertAnnotationsTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/XmlWithExplicitConvertAnnotationsTest.java index 4afbd506a1..77902dadf4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/XmlWithExplicitConvertAnnotationsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/XmlWithExplicitConvertAnnotationsTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.test.converter; +package org.hibernate.orm.test.mapping.converted.converter; import java.net.MalformedURLException; import java.util.Date; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/Address.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/Address.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/caching/Address.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/Address.java index 1413ad1804..d32a08c0c2 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/Address.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/Address.java @@ -4,13 +4,12 @@ * 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.test.converter.caching; +package org.hibernate.orm.test.mapping.converted.converter.caching; import javax.persistence.Cacheable; import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; -import javax.persistence.Lob; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicStructuredCachingOfConvertedValueTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicStructuredCachingOfConvertedValueTest.java new file mode 100644 index 0000000000..9264ea22a9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicStructuredCachingOfConvertedValueTest.java @@ -0,0 +1,114 @@ +/* + * 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.orm.test.mapping.converted.converter.caching; + +import java.util.Map; + +import org.hibernate.cache.spi.DomainDataRegion; +import org.hibernate.cache.spi.access.EntityDataAccess; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.persister.entity.EntityPersister; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * @author Steve Ebersole + */ +@ServiceRegistry( + settings = { + @Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true" ), + @Setting( name = AvailableSettings.CACHE_REGION_FACTORY, value = "org.hibernate.testing.cache.CachingRegionFactory" ), + @Setting( name = AvailableSettings.USE_STRUCTURED_CACHE, value = "true" ), + } +) +@DomainModel( annotatedClasses = Address.class ) +@SessionFactory +public class BasicStructuredCachingOfConvertedValueTest { + + @Test + @TestForIssue( jiraKey = "HHH-9615" ) + @SuppressWarnings("unchecked") + public void basicCacheStructureTest(SessionFactoryScope scope) { + EntityPersister persister = scope.getSessionFactory().getMetamodel().entityPersisters().get( Address.class.getName() ); + DomainDataRegion region = persister.getCacheAccessStrategy().getRegion(); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during store... + PostalAreaConverter.clearCounts(); + + scope.inTransaction( + (session) -> { + session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ); + } + ); + + scope.inTransaction( + (session) -> { + final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); + final Object cacheKey = entityDataAccess.generateCacheKey( + 1, + persister, + scope.getSessionFactory(), + null + ); + final Object cachedItem = entityDataAccess.get( session, cacheKey ); + final Map state = (Map) cachedItem; + // this is the point of the Jira.. that this "should be" the converted value + assertThat( state.get( "postalArea" ), instanceOf( PostalArea.class ) ); + } + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is(1) ); + assertThat( PostalAreaConverter.toDomainCallCount, is(0) ); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during load... + PostalAreaConverter.clearCounts(); + scope.getSessionFactory().getCache().evictAll(); + + scope.inTransaction( + (session) -> session.get( Address.class, 1 ) + ); + + scope.inTransaction( + (session) -> { + final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); + final Object cacheKey = entityDataAccess.generateCacheKey( + 1, + persister, + scope.getSessionFactory(), + null + ); + final Object cachedItem = entityDataAccess.get( session, cacheKey ); + final Map state = (Map) cachedItem; + // this is the point of the Jira.. that this "should be" the converted value + assertThat( state.get( "postalArea" ), instanceOf( PostalArea.class ) ); + } + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is(0 ) ); + assertThat( PostalAreaConverter.toDomainCallCount, is(1 ) ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Address" ).executeUpdate() + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java new file mode 100644 index 0000000000..fe3ddd8c74 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java @@ -0,0 +1,118 @@ +/* + * 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.orm.test.mapping.converted.converter.caching; + +import org.hibernate.cache.spi.DomainDataRegion; +import org.hibernate.cache.spi.access.EntityDataAccess; +import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.persister.entity.EntityPersister; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * @author Steve Ebersole + */ +@ServiceRegistry( + settings = { + @Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true" ), + @Setting( name = AvailableSettings.CACHE_REGION_FACTORY, value = "org.hibernate.testing.cache.CachingRegionFactory" ), + @Setting( name = AvailableSettings.USE_STRUCTURED_CACHE, value = "false" ), + } +) +@DomainModel( annotatedClasses = Address.class ) +@SessionFactory +public class BasicUnstructuredCachingOfConvertedValueTest { + + public static final int postalAreaAttributeIndex = 0; + + @Test + @TestForIssue( jiraKey = "HHH-9615" ) + @SuppressWarnings("unchecked") + public void basicCacheStructureTest(SessionFactoryScope scope) { + EntityPersister persister = scope.getSessionFactory() + .getMetamodel() + .entityPersisters() + .get( Address.class.getName() ); + final DomainDataRegion region = persister.getCacheAccessStrategy().getRegion(); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during store... + PostalAreaConverter.clearCounts(); + + scope.inTransaction( + (session) -> { + session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ); + } + ); + + scope.inTransaction( + (session) -> { + final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); + final Object cacheKey = entityDataAccess.generateCacheKey( + 1, + persister, + scope.getSessionFactory(), + null + ); + final Object cachedItem = entityDataAccess.get( session, cacheKey ); + final StandardCacheEntryImpl state = (StandardCacheEntryImpl) cachedItem; + // this is the point of the Jira.. that this "should be" the converted value + assertThat( state.getDisassembledState()[ postalAreaAttributeIndex ], instanceOf( PostalArea.class ) ); + } + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is( 1 ) ); + assertThat( PostalAreaConverter.toDomainCallCount, is( 0 ) ); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during load... + PostalAreaConverter.clearCounts(); + scope.getSessionFactory().getCache().evictAll(); + + scope.inTransaction( + (session) -> session.get( Address.class, 1 ) + ); + + scope.inTransaction( + (session) -> { + final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); + final Object cacheKey = entityDataAccess.generateCacheKey( + 1, + persister, + scope.getSessionFactory(), + null + ); + final Object cachedItem = entityDataAccess.get( session, cacheKey ); + final StandardCacheEntryImpl state = (StandardCacheEntryImpl) cachedItem; + // this is the point of the Jira.. that this "should be" the converted value + assertThat( state.getDisassembledState()[ postalAreaAttributeIndex ], instanceOf( PostalArea.class ) ); + } + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is( 0 ) ); + assertThat( PostalAreaConverter.toDomainCallCount, is( 1 ) ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Address" ).executeUpdate() + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalArea.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalArea.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalArea.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalArea.java index ada3d92ad7..f023b11a4f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalArea.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalArea.java @@ -4,7 +4,7 @@ * 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.test.converter.lob; +package org.hibernate.orm.test.mapping.converted.converter.caching; import org.hibernate.annotations.Immutable; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalAreaConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalAreaConverter.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalAreaConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalAreaConverter.java index 9e00901fbb..3761296d11 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalAreaConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/PostalAreaConverter.java @@ -4,7 +4,7 @@ * 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.test.converter.caching; +package org.hibernate.orm.test.mapping.converted.converter.caching; import javax.persistence.AttributeConverter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/State.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/State.java similarity index 89% rename from hibernate-core/src/test/java/org/hibernate/test/converter/caching/State.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/State.java index 335aed3c1f..3bd3763eb6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/State.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/caching/State.java @@ -4,7 +4,7 @@ * 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.test.converter.caching; +package org.hibernate.orm.test.mapping.converted.converter.caching; import org.hibernate.annotations.Immutable; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/CustomTypeConverterTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/CustomTypeConverterTest.java index fa3d6f9d06..b4435be7c2 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/CustomTypeConverterTest.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomConverter.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomConverter.java index 4d3024ccd0..fde63ae69f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomConverter.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; import javax.persistence.AttributeConverter; import javax.persistence.Converter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaType.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaType.java index 928a37fad9..59b45e7bf6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaType.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; /** * @author Steve Ebersole diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaTypeDescriptor.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaTypeDescriptor.java index 7bbf57a1e0..fa98a042e6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomJavaTypeDescriptor.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; import org.hibernate.internal.util.StringHelper; import org.hibernate.type.descriptor.WrapperOptions; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomSqlTypeDescriptor.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomSqlTypeDescriptor.java index 2773bd9561..147ae9c0f7 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyCustomSqlTypeDescriptor.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; import java.sql.CallableStatement; import java.sql.PreparedStatement; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyEntity.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyEntity.java index 0fbea16fd1..a31e374b9f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/MyEntity.java @@ -4,7 +4,7 @@ * 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.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; import javax.persistence.Basic; import javax.persistence.Entity; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/package-info.java similarity index 83% rename from hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/package-info.java index d444591b3c..ef5e2013a8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/custom/package-info.java @@ -9,4 +9,4 @@ * Test illustrating use of an AttributeConverter over custom * java / sql type descriptors */ -package org.hibernate.test.converter.custom; +package org.hibernate.orm.test.mapping.converted.converter.custom; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementConversionTest.java similarity index 69% rename from hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementConversionTest.java index 3ae560e885..a20b0d056c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementConversionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.elementCollection; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.util.HashSet; import java.util.Set; @@ -19,11 +19,12 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Table; -import org.hibernate.Session; - import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.junit.Assert.assertEquals; @@ -31,34 +32,36 @@ import static org.junit.Assert.assertEquals; * @author Steve Ebersole */ @TestForIssue( jiraKey = "HHH-8529" ) -public class CollectionCompositeElementConversionTest extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Disguise.class, ColorTypeConverter.class }; +@DomainModel( + annotatedClasses = { + CollectionCompositeElementConversionTest.Disguise.class, + CollectionCompositeElementConversionTest.ColorTypeConverter.class + } +) +@SessionFactory +public class CollectionCompositeElementConversionTest { + @Test + public void testElementCollectionConversion(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Disguise disguise = new Disguise( 1 ); + disguise.traits.add( new Traits( ColorType.BLUE, ColorType.RED ) ); + session.persist( disguise ); + } + ); + + scope.inTransaction( + (session) -> { + assertEquals( 1, session.get( Disguise.class, 1 ).traits.size() ); + } + ); } - @Test - public void testElementCollectionConversion() { - Session session = openSession(); - session.getTransaction().begin(); - Disguise disguise = new Disguise( 1 ); - disguise.traits.add( new Traits( ColorType.BLUE, ColorType.RED ) ); - session.persist( disguise ); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - assertEquals( 1, session.get( Disguise.class, 1 ).traits.size() ); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - disguise = session.get( Disguise.class, 1 ); - session.delete( disguise ); - session.getTransaction().commit(); - session.close(); + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Disguise" ).executeUpdate() + ); } @Entity( name = "Disguise" ) diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java similarity index 88% rename from hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java index 1a7db1e747..61a6d24c71 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.elementCollection; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.io.Serializable; import java.lang.reflect.Field; @@ -23,8 +23,6 @@ import javax.persistence.JoinColumn; import javax.persistence.Table; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.mapping.Component; @@ -33,10 +31,11 @@ import org.hibernate.mapping.Property; import org.hibernate.mapping.SimpleValue; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseUnitTestCase; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.ServiceRegistryScope; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.hamcrest.CoreMatchers; @@ -49,26 +48,18 @@ import static org.junit.Assert.assertThat; * @author Steve Ebersole */ @TestForIssue( jiraKey = "HHH-10277" ) -public class CollectionCompositeElementExplicitConversionTest extends BaseUnitTestCase { - private StandardServiceRegistry ssr; +@ServiceRegistry +public class CollectionCompositeElementExplicitConversionTest { private Field simpleValueAttributeConverterDescriptorField; - @Before + @BeforeAll public void setUp() throws Exception { - ssr = new StandardServiceRegistryBuilder().build(); simpleValueAttributeConverterDescriptorField = ReflectHelper.findField( SimpleValue.class, "attributeConverterDescriptor" ); } - @After - public void tearDown() { - if ( ssr != null ) { - StandardServiceRegistryBuilder.destroy( ssr ); - } - } - @Test - public void testCollectionOfEmbeddablesWithConvertedAttributes() throws Exception { - final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) + public void testCollectionOfEmbeddablesWithConvertedAttributes(ServiceRegistryScope scope) throws Exception { + final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( scope.getRegistry() ) .addAnnotatedClass( Disguise.class ) .addAnnotatedClass( Traits.class ) .buildMetadata(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementConversionTest.java similarity index 56% rename from hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementConversionTest.java index de8c5b11dd..a5533f6c21 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementConversionTest.java @@ -4,17 +4,13 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.elementCollection; - -import static org.junit.Assert.assertEquals; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - import javax.persistence.AttributeConverter; -import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.Converter; import javax.persistence.ElementCollection; @@ -24,55 +20,58 @@ import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; -import org.hibernate.Session; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; /** * @author Steve Ebersole */ @TestForIssue(jiraKey = "HHH-8529") -public class CollectionElementConversionTest extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Customer.class, ColorConverter.class }; - } +@DomainModel( annotatedClasses = { CollectionElementConversionTest.Customer.class, CollectionElementConversionTest.ColorConverter.class } ) +@SessionFactory +public class CollectionElementConversionTest { @Test - public void testElementCollectionConversion() { - Session session = openSession(); - session.getTransaction().begin(); - Customer customer = new Customer(); - customer.id = 1; - customer.set = new HashSet(); - customer.set.add(Color.RED); - customer.set.add(Color.GREEN); - customer.set.add(Color.BLUE); - customer.map = new HashMap(); - customer.map.put(Color.RED, Status.INACTIVE); - customer.map.put(Color.GREEN, Status.ACTIVE); - customer.map.put(Color.BLUE, Status.PENDING); - session.persist(customer); - session.getTransaction().commit(); - session.close(); + public void testElementCollectionConversion(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Customer customer = new Customer(); + customer.id = 1; + customer.set = new HashSet<>(); + customer.set.add(Color.RED); + customer.set.add(Color.GREEN); + customer.set.add(Color.BLUE); + customer.map = new HashMap<>(); + customer.map.put(Color.RED, Status.INACTIVE); + customer.map.put(Color.GREEN, Status.ACTIVE); + customer.map.put(Color.BLUE, Status.PENDING); + session.persist(customer); + } + ); - session = openSession(); - session.getTransaction().begin(); - assertEquals(customer.set, session.get(Customer.class, 1).set); - assertEquals(customer.map, session.get(Customer.class, 1).map); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - customer = session.get(Customer.class, 1); - session.delete(customer); - session.getTransaction().commit(); - session.close(); + scope.inTransaction( + (session) -> { + final Customer customer = session.get( Customer.class, 1 ); + assertEquals( customer.set, customer.set ); + assertEquals( customer.map, customer.map ); + } + ); } - @Entity + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Customer" ).executeUpdate() + ); + } + + @Entity( name = "Customer" ) @Table(name = "Customer") public static class Customer { @Id @@ -107,7 +106,7 @@ public class CollectionElementConversionTest extends BaseNonConfigCoreFunctional } } - public static enum Status { + public enum Status { ACTIVE, INACTIVE, PENDING diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementExplicitConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementExplicitConversionTest.java similarity index 70% rename from hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementExplicitConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementExplicitConversionTest.java index b56f044109..cb44001dc3 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/CollectionElementExplicitConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionElementExplicitConversionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.elementCollection; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.util.HashSet; import java.util.Set; @@ -21,11 +21,13 @@ import javax.persistence.JoinColumn; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.hibernate.Session; - import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.junit.Assert.assertEquals; @@ -33,37 +35,38 @@ import static org.junit.Assert.assertEquals; * @author Steve Ebersole */ @TestForIssue( jiraKey = "HHH-8529" ) -public class CollectionElementExplicitConversionTest extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - // NOTE : ColorTypeConverter is autoApply=false here - return new Class[] { Customer.class, ColorTypeConverter.class }; - } +@DomainModel( + annotatedClasses = { + CollectionElementExplicitConversionTest.Customer.class, + CollectionElementExplicitConversionTest.ColorTypeConverter.class + } +) +@SessionFactory +public class CollectionElementExplicitConversionTest { @Test - public void testElementCollectionConversion() { - Session session = openSession(); - session.getTransaction().begin(); - Customer customer = new Customer( 1 ); - customer.colors.add( ColorType.BLUE ); - session.persist( customer ); - session.getTransaction().commit(); - session.close(); + public void testElementCollectionConversion(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Customer customer = new Customer( 1 ); + customer.colors.add( ColorType.BLUE ); + session.persist( customer ); + } + ); - session = openSession(); - session.getTransaction().begin(); - assertEquals( 1, session.get( Customer.class, 1 ).colors.size() ); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - customer = session.get( Customer.class, 1 ); - session.delete( customer ); - session.getTransaction().commit(); - session.close(); + scope.inTransaction( + (session) -> { + assertEquals( 1, session.get( Customer.class, 1 ).colors.size() ); + } + ); } + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Customer" ).executeUpdate() + ); + } @Entity( name = "Customer" ) @Table( name = "CUST" ) public static class Customer { diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/ElementCollectionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/ElementCollectionTests.java similarity index 75% rename from hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/ElementCollectionTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/ElementCollectionTests.java index ce72adae15..1e9f33e6cb 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/elementCollection/ElementCollectionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/ElementCollectionTests.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.elementCollection; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.net.MalformedURLException; import java.util.HashMap; @@ -24,7 +24,6 @@ import javax.persistence.JoinColumn; import javax.persistence.MapKeyColumn; import javax.persistence.Table; -import org.hibernate.Session; import org.hibernate.mapping.Collection; import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.PersistentClass; @@ -32,8 +31,12 @@ import org.hibernate.mapping.Property; import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.DomainModelScope; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; @@ -48,16 +51,16 @@ import static org.junit.Assert.assertNotNull; * @author Steve Ebersole */ @TestForIssue( jiraKey = "HHH-9495" ) -public class ElementCollectionTests extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { TheEntity.class }; - } +@DomainModel( + annotatedClasses = ElementCollectionTests.TheEntity.class +) +@SessionFactory +public class ElementCollectionTests { @Test - public void testSimpleConvertUsage() throws MalformedURLException { + public void testSimpleConvertUsage(DomainModelScope modelScope, SessionFactoryScope sfScope) throws MalformedURLException { // first some assertions of the metamodel - PersistentClass entityBinding = metadata().getEntityBinding( TheEntity.class.getName() ); + PersistentClass entityBinding = modelScope.getDomainModel().getEntityBinding( TheEntity.class.getName() ); assertNotNull( entityBinding ); Property setAttributeBinding = entityBinding.getProperty( "set" ); @@ -70,24 +73,30 @@ public class ElementCollectionTests extends BaseNonConfigCoreFunctionalTestCase assertTyping( AttributeConverterTypeAdapter.class, mapBinding.getElement().getType() ); // now lets try to use the model, integration-testing-style! - TheEntity entity = new TheEntity(1); + TheEntity entity = new TheEntity( 1 ); - Session s = openSession(); - s.beginTransaction(); - s.save( entity ); - s.getTransaction().commit(); - s.close(); + sfScope.inTransaction( + (session) -> { + session.save( entity ); + } + ); - s = openSession(); - s.beginTransaction(); - TheEntity retrieved = (TheEntity) s.load( TheEntity.class, 1 ); - assertEquals( 1, retrieved.getSet().size() ); - assertEquals(new ValueType("set_value"), retrieved.getSet().iterator().next()); - assertEquals(1, retrieved.getMap().size()); - assertEquals(new ValueType("map_value"), retrieved.getMap().get(new ValueType("map_key"))); - s.delete( retrieved ); - s.getTransaction().commit(); - s.close(); + sfScope.inTransaction( + (session) -> { + TheEntity retrieved = (TheEntity) session.load( TheEntity.class, 1 ); + assertEquals( 1, retrieved.getSet().size() ); + assertEquals( new ValueType( "set_value" ), retrieved.getSet().iterator().next() ); + assertEquals( 1, retrieved.getMap().size() ); + assertEquals( new ValueType( "map_value" ), retrieved.getMap().get( new ValueType( "map_key" ) ) ); + } + ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete TheEntity" ).executeUpdate() + ); } /** diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java similarity index 85% rename from hibernate-core/src/test/java/org/hibernate/test/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java index 0c83891689..3f55f9b1fd 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/generics/ParameterizedAttributeConverterParameterTypeTest.java @@ -4,12 +4,11 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.generics; +package org.hibernate.orm.test.mapping.converted.converter.generics; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; - import javax.persistence.AttributeConverter; import javax.persistence.Converter; import javax.persistence.Entity; @@ -17,8 +16,6 @@ import javax.persistence.Id; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AttributeConverterDefinition; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.PersistentClass; @@ -26,10 +23,9 @@ import org.hibernate.mapping.Property; import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseUnitTestCase; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.ServiceRegistryScope; +import org.junit.jupiter.api.Test; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; @@ -42,33 +38,8 @@ import static org.junit.Assert.assertTrue; * @author Svein Baardsen * @author Steve Ebersole */ -public class ParameterizedAttributeConverterParameterTypeTest extends BaseUnitTestCase { - - private static StandardServiceRegistry ssr; - - @BeforeClass - public static void beforeClass() { - ssr = new StandardServiceRegistryBuilder().build(); - } - - @AfterClass - public static void afterClass() { - if ( ssr != null ) { - StandardServiceRegistryBuilder.destroy( ssr ); - } - } - - public static class CustomAttributeConverter implements AttributeConverter, Integer> { - @Override - public Integer convertToDatabaseColumn(List attribute) { - return attribute.size(); - } - - @Override - public List convertToEntityAttribute(Integer dbData) { - return new ArrayList(dbData); - } - } +@ServiceRegistry +public class ParameterizedAttributeConverterParameterTypeTest { @Test @TestForIssue(jiraKey = "HHH-8804") @@ -79,8 +50,8 @@ public class ParameterizedAttributeConverterParameterTypeTest extends BaseUnitTe @Test @TestForIssue( jiraKey = "HHH-10050" ) - public void testNestedTypeParameterAutoApplication() { - final Metadata metadata = new MetadataSources( ssr ) + public void testNestedTypeParameterAutoApplication(ServiceRegistryScope scope) { + final Metadata metadata = new MetadataSources( scope.getRegistry() ) .addAnnotatedClass( SampleEntity.class ) .getMetadataBuilder() .applyAttributeConverter( IntegerListConverter.class ) @@ -186,6 +157,17 @@ public class ParameterizedAttributeConverterParameterTypeTest extends BaseUnitTe return strings; } } + public static class CustomAttributeConverter implements AttributeConverter, Integer> { + @Override + public Integer convertToDatabaseColumn(List attribute) { + return attribute.size(); + } + + @Override + public List convertToEntityAttribute(Integer dbData) { + return new ArrayList(dbData); + } + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/inheritence/AttributeConverterOnSuperclassTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/inheritence/AttributeConverterOnSuperclassTest.java similarity index 78% rename from hibernate-core/src/test/java/org/hibernate/test/converter/inheritence/AttributeConverterOnSuperclassTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/inheritence/AttributeConverterOnSuperclassTest.java index 979dc51562..eab10609e9 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/inheritence/AttributeConverterOnSuperclassTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/inheritence/AttributeConverterOnSuperclassTest.java @@ -1,11 +1,19 @@ -package org.hibernate.test.converter.inheritence; +/* + * 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.orm.test.mapping.converted.converter.inheritence; import java.util.List; import javax.persistence.AttributeConverter; +import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; import org.hibernate.cfg.AttributeConverterDefinition; import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.boot.BootstrapContextImpl; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.junit.Test; @@ -39,8 +47,13 @@ public class AttributeConverterOnSuperclassTest extends BaseUnitTestCase { @Test public void testAttributeConverterOnSuperclass() { - AttributeConverterDefinition def = AttributeConverterDefinition.from( StringIntegerConverterSubclass.class ); - assertEquals( String.class, def.getEntityAttributeType() ); + final BootstrapContextImpl bootstrapContext = BootstrapContextImpl.INSTANCE; + final ClassBasedConverterDescriptor converterDescriptor = new ClassBasedConverterDescriptor( + StringIntegerConverterSubclass.class, + bootstrapContext.getClassmateContext() + ); + + assertEquals( String.class, converterDescriptor.getDomainValueResolvedType().getErasedType() ); } public interface StringLongAttributeConverter extends AttributeConverter { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/literal/QueryLiteralTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/literal/QueryLiteralTest.java new file mode 100644 index 0000000000..73355e15dd --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/literal/QueryLiteralTest.java @@ -0,0 +1,429 @@ +/* + * 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 . + */ +package org.hibernate.orm.test.mapping.converted.converter.literal; + +import javax.persistence.AttributeConverter; +import javax.persistence.Column; +import javax.persistence.Convert; +import javax.persistence.Converter; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.query.Query; +import org.hibernate.sql.ast.SqlTreeCreationException; + +import org.hibernate.testing.orm.ExceptionHelper; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * @author Janario Oliveira + * @author Steve Ebersole + */ +@DomainModel( + annotatedClasses = { + QueryLiteralTest.EntityConverter.class, + QueryLiteralTest.NumberIntegerConverter.class, + QueryLiteralTest.NumberStringConverter.class, + QueryLiteralTest.StringWrapperConverter.class, + QueryLiteralTest.IntegerWrapperConverter.class + } +) +@SessionFactory +public class QueryLiteralTest { + @Test + public void testIntegerWrapper(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setIntegerWrapper( new IntegerWrapper( 10 ) ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.integerWrapper=10", session ) + ); + + assertNotNull( loaded ); + assertEquals( 10, created.getIntegerWrapper().getValue() ); + } + + @Test + public void testIntegerWrapperThrowsException(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setIntegerWrapper( new IntegerWrapper( 10 ) ); + session.persist( entity ); + + return entity; + } + ); + + try { + scope.fromTransaction( + (session) -> find( created.id, "e.integerWrapper = '10'", session ) + ); + fail( "Should throw Exception!" ); + } + catch (Exception e) { + final Throwable rootCause = ExceptionHelper.getRootCause( e ); + assertThat( rootCause, instanceOf( SqlTreeCreationException.class ) ); + assertThat( rootCause.getMessage(), startsWith( "QueryLiteral type [" ) ); + assertThat( rootCause.getMessage(), containsString( "] did not match domain Java-type [" ) ); + assertThat( rootCause.getMessage(), containsString( "] nor JDBC Java-type [" ) ); + } + } + + @Test + public void testStringWrapper(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setStringWrapper( new StringWrapper( "TEN" ) ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.stringWrapper='TEN'", session ) + ); + + assertNotNull( loaded ); + assertEquals( "TEN", loaded.getStringWrapper().getValue() ); + } + + @Test + public void testSameTypeConverter(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setSameTypeConverter( "HUNDRED" ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.sameTypeConverter='HUNDRED'", session ) + ); + + assertNotNull( loaded ); + assertEquals( "HUNDRED", loaded.getSameTypeConverter() ); + + scope.inTransaction( + (session) -> { + String value = (String) session.createNativeQuery( "select e.same_type_converter from entity_converter e where e.id=:id" ) + .setParameter( "id", loaded.getId() ) + .uniqueResult(); + assertEquals( "VALUE_HUNDRED", value ); + } + ); + } + + @Test + public void testEnumOrdinal(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setLetterOrdinal( Letter.B ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.letterOrdinal=" + Letter.B.ordinal(), session ) + ); + + assertNotNull( loaded ); + assertEquals( Letter.B, loaded.getLetterOrdinal() ); + } + + @Test + public void testEnumString(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setLetterString( Letter.C ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.letterString='" + Letter.C.name() + "'", session ) + ); + + assertNotNull( loaded ); + assertEquals( Letter.C, loaded.getLetterString() ); + } + + @Test + public void testNumberImplicit(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setNumbersImplicit( Numbers.THREE ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.numbersImplicit=" + ( Numbers.THREE.ordinal() + 1 ), session ) + ); + + assertNotNull( loaded ); + assertEquals( Numbers.THREE, loaded.getNumbersImplicit() ); + } + + @Test + public void testNumberImplicitOverridden(SessionFactoryScope scope) { + final EntityConverter created = scope.fromTransaction( + (session) -> { + EntityConverter entity = new EntityConverter(); + entity.setNumbersImplicitOverridden( Numbers.TWO ); + session.persist( entity ); + + return entity; + } + ); + + final EntityConverter loaded = scope.fromTransaction( + (session) -> find( created.id, "e.numbersImplicitOverridden='" + ( Numbers.TWO.ordinal() + 1 ) + "'", session ) + ); + + assertNotNull( loaded ); + assertEquals( Numbers.TWO, loaded.getNumbersImplicitOverridden() ); + } + + private EntityConverter find(int id, String queryLiteral, SessionImplementor session) { + final String qryBase = "select e from EntityConverter e where e.id=:id and "; + final Query query = session.createQuery(qryBase + queryLiteral, EntityConverter.class ); + query.setParameter( "id", id ); + return query.uniqueResult(); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete EntityConverter" ).executeUpdate() + ); + } + + public enum Letter { + A, B, C + } + + public enum Numbers { + ONE, TWO, THREE + } + + @Converter(autoApply = true) + public static class NumberIntegerConverter implements AttributeConverter { + @Override + public Integer convertToDatabaseColumn(Numbers attribute) { + return attribute == null ? null : attribute.ordinal() + 1; + } + + @Override + public Numbers convertToEntityAttribute(Integer dbData) { + return dbData == null ? null : Numbers.values()[dbData - 1]; + } + } + + @Converter + public static class NumberStringConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(Numbers attribute) { + return attribute == null ? null : Integer.toString( attribute.ordinal() + 1 ); + } + + @Override + public Numbers convertToEntityAttribute(String dbData) { + return dbData == null ? null : Numbers.values()[Integer.parseInt( dbData ) - 1]; + } + } + + + @Converter(autoApply = true) + public static class IntegerWrapperConverter implements AttributeConverter { + @Override + public Integer convertToDatabaseColumn(IntegerWrapper attribute) { + return attribute == null ? null : attribute.getValue(); + } + + @Override + public IntegerWrapper convertToEntityAttribute(Integer dbData) { + return dbData == null ? null : new IntegerWrapper( dbData ); + } + } + + @Converter(autoApply = true) + public static class StringWrapperConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(StringWrapper attribute) { + return attribute == null ? null : attribute.getValue(); + } + + @Override + public StringWrapper convertToEntityAttribute(String dbData) { + return dbData == null ? null : new StringWrapper( dbData ); + } + } + + @Converter + public static class PreFixedStringConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(String attribute) { + return attribute == null ? null : "VALUE_" + attribute; + } + + @Override + public String convertToEntityAttribute(String dbData) { + return dbData == null ? null : dbData.substring( 6 ); + } + } + + @Entity(name = "EntityConverter") + @Table(name = "entity_converter") + public static class EntityConverter { + @Id + @GeneratedValue + private Integer id; + + private Letter letterOrdinal; + @Enumerated(EnumType.STRING) + private Letter letterString; + + private Numbers numbersImplicit; + @Convert(converter = NumberStringConverter.class) + private Numbers numbersImplicitOverridden; + + private IntegerWrapper integerWrapper; + private StringWrapper stringWrapper; + + @Convert(converter = PreFixedStringConverter.class) + @Column(name = "same_type_converter") + private String sameTypeConverter; + + public Integer getId() { + return id; + } + + public Letter getLetterOrdinal() { + return letterOrdinal; + } + + public void setLetterOrdinal(Letter letterOrdinal) { + this.letterOrdinal = letterOrdinal; + } + + public Letter getLetterString() { + return letterString; + } + + public void setLetterString(Letter letterString) { + this.letterString = letterString; + } + + public Numbers getNumbersImplicit() { + return numbersImplicit; + } + + public void setNumbersImplicit(Numbers numbersImplicit) { + this.numbersImplicit = numbersImplicit; + } + + public Numbers getNumbersImplicitOverridden() { + return numbersImplicitOverridden; + } + + public void setNumbersImplicitOverridden(Numbers numbersImplicitOverridden) { + this.numbersImplicitOverridden = numbersImplicitOverridden; + } + + public IntegerWrapper getIntegerWrapper() { + return integerWrapper; + } + + public void setIntegerWrapper(IntegerWrapper integerWrapper) { + this.integerWrapper = integerWrapper; + } + + public StringWrapper getStringWrapper() { + return stringWrapper; + } + + public void setStringWrapper(StringWrapper stringWrapper) { + this.stringWrapper = stringWrapper; + } + + public String getSameTypeConverter() { + return sameTypeConverter; + } + + public void setSameTypeConverter(String sameTypeConverter) { + this.sameTypeConverter = sameTypeConverter; + } + } + + public static class IntegerWrapper { + private final int value; + + public IntegerWrapper(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + @Override + public String toString() { + return String.format( "IntegerWrapper{value=%d}", value); + } + } + + public static class StringWrapper { + private final String value; + + public StringWrapper(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/Address.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/Address.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/converter/lob/Address.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/Address.java index 621fd75185..e784c71ca3 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/Address.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/Address.java @@ -4,7 +4,7 @@ * 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.test.converter.lob; +package org.hibernate.orm.test.mapping.converted.converter.lob; import javax.persistence.Cacheable; import javax.persistence.Convert; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/ConverterAndLobTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/ConverterAndLobTest.java new file mode 100644 index 0000000000..8574fd99ac --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/ConverterAndLobTest.java @@ -0,0 +1,65 @@ +/* + * 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.orm.test.mapping.converted.converter.lob; + +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * @author Steve Ebersole + */ +@ServiceRegistry( settings = @Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "false" ) ) +@DomainModel( annotatedClasses = Address.class ) +@SessionFactory +public class ConverterAndLobTest { + + @Test + @TestForIssue( jiraKey = "HHH-9615" ) + public void basicTest(SessionFactoryScope scope) { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during store... + PostalAreaConverter.clearCounts(); + + scope.inTransaction( + (session) -> session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ) + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is(1) ); + assertThat( PostalAreaConverter.toDomainCallCount, is(0) ); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // test during load... + PostalAreaConverter.clearCounts(); + + scope.inTransaction( + (session) -> session.get( Address.class, 1 ) + ); + + assertThat( PostalAreaConverter.toDatabaseCallCount, is(0) ); + assertThat( PostalAreaConverter.toDomainCallCount, is(1) ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Address" ).executeUpdate() + ); + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalArea.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalArea.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalArea.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalArea.java index 296ca148ce..7c973145be 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/PostalArea.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalArea.java @@ -4,7 +4,7 @@ * 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.test.converter.caching; +package org.hibernate.orm.test.mapping.converted.converter.lob; import org.hibernate.annotations.Immutable; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalAreaConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalAreaConverter.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalAreaConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalAreaConverter.java index b76c578c82..b7840df508 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/PostalAreaConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/PostalAreaConverter.java @@ -4,7 +4,7 @@ * 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.test.converter.lob; +package org.hibernate.orm.test.mapping.converted.converter.lob; import javax.persistence.AttributeConverter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/State.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/State.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/test/converter/lob/State.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/State.java index 034962c9bb..22bde1abe9 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/State.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/lob/State.java @@ -4,7 +4,7 @@ * 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.test.converter.lob; +package org.hibernate.orm.test.mapping.converted.converter.lob; import org.hibernate.annotations.Immutable; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorType.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorType.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorType.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorType.java index ed19fa39cc..97e6ea0d06 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorType.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorType.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.map; +package org.hibernate.orm.test.mapping.converted.converter.map; /** * @author Steve Ebersole diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorTypeConverter.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorTypeConverter.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorTypeConverter.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorTypeConverter.java index a83208e7ca..0977e08a92 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/map/ColorTypeConverter.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/ColorTypeConverter.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.map; +package org.hibernate.orm.test.mapping.converted.converter.map; import javax.persistence.AttributeConverter; import javax.persistence.Converter; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapElementConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapElementConversionTest.java similarity index 70% rename from hibernate-core/src/test/java/org/hibernate/test/converter/map/MapElementConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapElementConversionTest.java index 4d571a9c5f..ae81b97cd4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapElementConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapElementConversionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.map; +package org.hibernate.orm.test.mapping.converted.converter.map; import java.util.HashMap; import java.util.Map; @@ -20,11 +20,12 @@ import javax.persistence.JoinColumn; import javax.persistence.MapKeyColumn; import javax.persistence.Table; -import org.hibernate.Session; - import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.junit.Assert.assertEquals; @@ -32,34 +33,37 @@ import static org.junit.Assert.assertEquals; * @author Steve Ebersole */ @TestForIssue( jiraKey = "HHH-8529" ) -public class MapElementConversionTest extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Customer.class, ColorTypeConverter.class }; +@DomainModel( + annotatedClasses = { + MapElementConversionTest.Customer.class, + MapElementConversionTest.ColorTypeConverter.class, + } +) +@SessionFactory +public class MapElementConversionTest { + @Test + public void testElementCollectionConversion(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> { + Customer customer = new Customer( 1 ); + customer.colors.put( "eyes", ColorType.BLUE ); + session.persist( customer ); + } + ); + + scope.inTransaction( + (session) -> { + assertEquals( 1, session.get( Customer.class, 1 ).colors.size() ); + } + ); + } - @Test - public void testElementCollectionConversion() { - Session session = openSession(); - session.getTransaction().begin(); - Customer customer = new Customer( 1 ); - customer.colors.put( "eyes", ColorType.BLUE ); - session.persist( customer ); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - assertEquals( 1, session.get( Customer.class, 1 ).colors.size() ); - session.getTransaction().commit(); - session.close(); - - session = openSession(); - session.getTransaction().begin(); - customer = session.get( Customer.class, 1 ); - session.delete( customer ); - session.getTransaction().commit(); - session.close(); + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete Customer" ).executeUpdate() + ); } @Entity( name = "Customer" ) diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyAttributeConverterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyAttributeConverterTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyAttributeConverterTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyAttributeConverterTest.java index 6a8c077cff..2dec7dccbe 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyAttributeConverterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyAttributeConverterTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.map; +package org.hibernate.orm.test.mapping.converted.converter.map; import java.util.HashMap; import java.util.Map; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyConversionTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyConversionTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyConversionTest.java index 9a7d513144..e2e1d904ed 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/map/MapKeyConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/map/MapKeyConversionTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.converter.map; +package org.hibernate.orm.test.mapping.converted.converter.map; import java.util.HashMap; import java.util.Map; diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/LongToDateConversionTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/LongToDateConversionTest.java deleted file mode 100644 index 13ca0c6573..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/LongToDateConversionTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.test.converter; - -import javax.persistence.AttributeConverter; -import javax.persistence.Column; -import javax.persistence.Convert; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.TemporalType; -import java.io.Serializable; -import java.util.Date; -import java.util.stream.Stream; - -import org.hibernate.Session; -import org.hibernate.query.Query; - -import org.junit.Test; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -/** - * @author Andrea Boriero - */ -@TestForIssue(jiraKey = "HHH-10959") -public class LongToDateConversionTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {TestEntity.class}; - } - - @Override - protected void prepareTest() throws Exception { - try (Session session = openSession()) { - session.getTransaction().begin(); - TestEntity entity = new TestEntity(); - entity.setDate( new DateAttribute( System.currentTimeMillis() ) ); - try { - session.persist( entity ); - session.getTransaction().commit(); - } - catch (Exception e) { - if ( session.getTransaction().isActive() ) { - session.getTransaction().rollback(); - } - throw e; - } - } - } - - @Override - protected boolean isCleanupTestDataRequired() { - return true; - } - - @Override - protected void cleanupTestData() throws Exception { - try (Session session = openSession()) { - session.getTransaction().begin(); - try { - session.createQuery( "delete from TestEntity" ).executeUpdate(); - session.getTransaction().commit(); - } - catch (Exception e) { - if ( session.getTransaction().isActive() ) { - session.getTransaction().rollback(); - } - throw e; - } - } - } - - @Test - public void testSetParameter() throws Exception { - try (Session session = openSession()) { - final Query query = session.createQuery( - "SELECT e FROM TestEntity e WHERE e.date <= :ts", - TestEntity.class - ).setParameter( "ts", new DateAttribute( System.currentTimeMillis() ), TemporalType.TIMESTAMP ); - - final Stream stream = query.stream(); - - assertThat( stream.count(), is( 1L ) ); - } - } - - @Entity(name = "TestEntity") - @Table(name = "TEST_ENTITY") - public static class TestEntity { - - @Id - @GeneratedValue - private long id; - - @Convert(converter = DateAttributeConverter.class) - @Column(name = "attribute_date") - private DateAttribute date; - - public DateAttribute getDate() { - return date; - } - - public void setDate(DateAttribute date) { - this.date = date; - } - } - - public static class DateAttribute implements Serializable { - private long field; - - public DateAttribute(long field) { - this.field = field; - } - } - - public static class DateAttributeConverter implements AttributeConverter { - - @Override - public Date convertToDatabaseColumn(DateAttribute attribute) { - if ( attribute == null ) { - return null; - } - return new Date( attribute.field ); - } - - @Override - public DateAttribute convertToEntityAttribute(Date dbData) { - if ( dbData == null ) { - return null; - } - return new DateAttribute( dbData.getTime() ); - } - - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicStructuredCachingOfConvertedValueTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicStructuredCachingOfConvertedValueTest.java deleted file mode 100644 index b84efe49f4..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicStructuredCachingOfConvertedValueTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.test.converter.caching; - -import java.util.Map; - -import org.hibernate.Session; -import org.hibernate.cache.spi.DomainDataRegion; -import org.hibernate.cache.spi.access.EntityDataAccess; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.persister.entity.EntityPersister; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.cache.CachingRegionFactory; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * @author Steve Ebersole - */ -public class BasicStructuredCachingOfConvertedValueTest extends BaseNonConfigCoreFunctionalTestCase { - - @Test - @TestForIssue( jiraKey = "HHH-9615" ) - @SuppressWarnings("unchecked") - public void basicCacheStructureTest() { - EntityPersister persister = sessionFactory().getMetamodel().entityPersisters().get( Address.class.getName() ); - DomainDataRegion region = persister.getCacheAccessStrategy().getRegion(); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during store... - PostalAreaConverter.clearCounts(); - - Session session = openSession(); - session.getTransaction().begin(); - session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ); - session.getTransaction().commit(); - session.close(); - - { - inSession( - s -> { - final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); - final Object cacheKey = entityDataAccess.generateCacheKey( - 1, - persister, - sessionFactory(), - null - ); - final Object cachedItem = entityDataAccess.get( s, cacheKey ); - final Map state = (Map) cachedItem; - // this is the point of the Jira.. that this "should be" the converted value - assertThat( state.get( "postalArea" ), instanceOf( PostalArea.class ) ); - } - ); - } - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(1) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(0) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during load... - PostalAreaConverter.clearCounts(); - sessionFactory().getCache().evictAll(); - - session = openSession(); - session.getTransaction().begin(); - Address address = session.get( Address.class, 1 ); - session.getTransaction().commit(); - session.close(); - - { - inSession( - s -> { - final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); - final Object cacheKey = entityDataAccess.generateCacheKey( - 1, - persister, - sessionFactory(), - null - ); - final Object cachedItem = entityDataAccess.get( s, cacheKey ); - final Map state = (Map) cachedItem; - // this is the point of the Jira.. that this "should be" the converted value - assertThat( state.get( "postalArea" ), instanceOf( PostalArea.class ) ); - } - ); - } - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(0) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(1) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // cleanup - session = openSession(); - session.getTransaction().begin(); - session.delete( address ); - session.getTransaction().commit(); - session.close(); - } - - - @Override - protected void addSettings(Map settings) { - super.addSettings( settings ); - - settings.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" ); - settings.put( AvailableSettings.CACHE_REGION_FACTORY, CachingRegionFactory.class ); - settings.put( AvailableSettings.USE_STRUCTURED_CACHE, "true" ); - - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Address.class }; - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java deleted file mode 100644 index fc312501e2..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/caching/BasicUnstructuredCachingOfConvertedValueTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.test.converter.caching; - -import java.util.Map; - -import org.hibernate.Session; -import org.hibernate.cache.spi.DomainDataRegion; -import org.hibernate.cache.spi.access.EntityDataAccess; -import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.persister.entity.EntityPersister; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.cache.CachingRegionFactory; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * @author Steve Ebersole - */ -public class BasicUnstructuredCachingOfConvertedValueTest extends BaseNonConfigCoreFunctionalTestCase { - - public static final int postalAreaAttributeIndex = 0; - - @Test - @TestForIssue( jiraKey = "HHH-9615" ) - @SuppressWarnings("unchecked") - public void basicCacheStructureTest() { - EntityPersister persister = sessionFactory().getMetamodel().entityPersisters().get( Address.class.getName() ); - final DomainDataRegion region = persister.getCacheAccessStrategy().getRegion(); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during store... - PostalAreaConverter.clearCounts(); - - Session session = openSession(); - session.getTransaction().begin(); - session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ); - session.getTransaction().commit(); - session.close(); - - { - inSession( - s -> { - final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); - final Object cacheKey = entityDataAccess.generateCacheKey( - 1, - persister, - sessionFactory(), - null - ); - final Object cachedItem = entityDataAccess.get( s, cacheKey ); - final StandardCacheEntryImpl state = (StandardCacheEntryImpl) cachedItem; - // this is the point of the Jira.. that this "should be" the converted value - assertThat( state.getDisassembledState()[postalAreaAttributeIndex], instanceOf( PostalArea.class ) ); - } - ); - } - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(1) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(0) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during load... - PostalAreaConverter.clearCounts(); - sessionFactory().getCache().evictAll(); - - session = openSession(); - session.getTransaction().begin(); - Address address = session.get( Address.class, 1 ); - session.getTransaction().commit(); - session.close(); - - { - inSession( - s -> { - final EntityDataAccess entityDataAccess = region.getEntityDataAccess( persister.getNavigableRole() ); - final Object cacheKey = entityDataAccess.generateCacheKey( - 1, - persister, - sessionFactory(), - null - ); - final Object cachedItem = entityDataAccess.get( s, cacheKey ); - final StandardCacheEntryImpl state = (StandardCacheEntryImpl) cachedItem; - // this is the point of the Jira.. that this "should be" the converted value - assertThat( state.getDisassembledState()[postalAreaAttributeIndex], instanceOf( PostalArea.class ) ); - } - ); - } - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(0) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(1) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // cleanup - session = openSession(); - session.getTransaction().begin(); - session.delete( address ); - session.getTransaction().commit(); - session.close(); - } - - - @Override - protected void addSettings(Map settings) { - super.addSettings( settings ); - - settings.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" ); - settings.put( AvailableSettings.CACHE_REGION_FACTORY, CachingRegionFactory.class ); - settings.put( AvailableSettings.USE_STRUCTURED_CACHE, "false" ); - - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Address.class }; - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java deleted file mode 100644 index 800b9f6e56..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.test.converter.literal; - -import javax.persistence.AttributeConverter; -import javax.persistence.Column; -import javax.persistence.Convert; -import javax.persistence.Converter; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.hibernate.query.Query; -import org.hibernate.QueryException; -import org.hibernate.Session; - -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Janario Oliveira - */ -public class QueryLiteralTest extends BaseNonConfigCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - EntityConverter.class, NumberIntegerConverter.class, NumberStringConverter.class, - StringWrapperConverter.class, IntegerWrapperConverter.class - }; - } - - @Test - public void testIntegerWrapper() { - EntityConverter entity = new EntityConverter(); - entity.setIntegerWrapper( new IntegerWrapper( 10 ) ); - save( entity ); - - entity = find( entity.getId(), "e.integerWrapper=10" ); - - assertNotNull( entity ); - assertEquals( 10, entity.getIntegerWrapper().getValue() ); - } - - @Test - public void testIntegerWrapperThrowsException() { - EntityConverter entity = new EntityConverter(); - entity.setIntegerWrapper( new IntegerWrapper( 10 ) ); - save( entity ); - - try { - find( entity.getId(), "e.integerWrapper='10'" ); - fail("Should throw QueryException!"); - } - catch (IllegalArgumentException e) { - assertTyping( QueryException.class, e.getCause() ); - assertTrue( e.getMessage().contains( "AttributeConverter domain-model attribute type [org.hibernate.test.converter.literal.QueryLiteralTest$IntegerWrapper] and JDBC type [java.lang.Integer] did not match query literal type [java.lang.String]" ) ); - } - } - - @Test - public void testStringWrapper() { - EntityConverter entity = new EntityConverter(); - entity.setStringWrapper( new StringWrapper( "TEN" ) ); - save( entity ); - - entity = find( entity.getId(), "e.stringWrapper='TEN'" ); - - assertNotNull( entity ); - assertEquals( "TEN", entity.getStringWrapper().getValue() ); - } - - @Test - public void testSameTypeConverter() { - EntityConverter entity = new EntityConverter(); - entity.setSameTypeConverter( "HUNDRED" ); - save( entity ); - - entity = find( entity.getId(), "e.sameTypeConverter='HUNDRED'" ); - - assertNotNull( entity ); - assertEquals( "HUNDRED", entity.getSameTypeConverter() ); - - Session session = openSession(); - String value = (String) session.createNativeQuery( "select e.same_type_converter from entity_converter e where e.id=:id" ) - .setParameter( "id", entity.getId() ) - .uniqueResult(); - assertEquals( "VALUE_HUNDRED", value ); - session.close(); - } - - @Test - public void testEnumOrdinal() { - EntityConverter entity = new EntityConverter(); - entity.setLetterOrdinal( Letter.B ); - save( entity ); - - entity = find( entity.getId(), "e.letterOrdinal=" + Letter.B.ordinal() ); - - assertNotNull( entity ); - assertEquals( Letter.B, entity.getLetterOrdinal() ); - } - - @Test - public void testEnumString() { - EntityConverter entity = new EntityConverter(); - entity.setLetterString( Letter.C ); - save( entity ); - - entity = find( entity.getId(), "e.letterString='" + Letter.C.name() + "'" ); - - assertNotNull( entity ); - assertEquals( Letter.C, entity.getLetterString() ); - } - - @Test - public void testNumberImplicit() { - EntityConverter entity = new EntityConverter(); - entity.setNumbersImplicit( Numbers.THREE ); - save( entity ); - - entity = find( entity.getId(), "e.numbersImplicit=" + ( Numbers.THREE.ordinal() + 1 ) ); - - assertNotNull( entity ); - assertEquals( Numbers.THREE, entity.getNumbersImplicit() ); - } - - @Test - public void testNumberImplicitOverrided() { - EntityConverter entity = new EntityConverter(); - entity.setNumbersImplicitOverrided( Numbers.TWO ); - save( entity ); - - entity = find( entity.getId(), "e.numbersImplicitOverrided='" + ( Numbers.TWO.ordinal() + 1 ) + "'" ); - - assertNotNull( entity ); - assertEquals( Numbers.TWO, entity.getNumbersImplicitOverrided() ); - } - - private void save(EntityConverter entity) { - Session session = openSession(); - session.beginTransaction(); - session.persist( entity ); - - session.getTransaction().commit(); - session.close(); - } - - private EntityConverter find(int id, String queryLiteral) { - Session session = openSession(); - Query query = session.createQuery( - "select e from EntityConverter e where e.id=:id and " + queryLiteral ); - query.setParameter( "id", id ); - EntityConverter entity = (EntityConverter) query.uniqueResult(); - session.close(); - return entity; - } - - public enum Letter { - A, B, C - } - - public enum Numbers { - ONE, TWO, THREE - } - - @Converter(autoApply = true) - public static class NumberIntegerConverter implements AttributeConverter { - @Override - public Integer convertToDatabaseColumn(Numbers attribute) { - return attribute == null ? null : attribute.ordinal() + 1; - } - - @Override - public Numbers convertToEntityAttribute(Integer dbData) { - return dbData == null ? null : Numbers.values()[dbData - 1]; - } - } - - @Converter - public static class NumberStringConverter implements AttributeConverter { - @Override - public String convertToDatabaseColumn(Numbers attribute) { - return attribute == null ? null : Integer.toString( attribute.ordinal() + 1 ); - } - - @Override - public Numbers convertToEntityAttribute(String dbData) { - return dbData == null ? null : Numbers.values()[Integer.parseInt( dbData ) - 1]; - } - } - - - @Converter(autoApply = true) - public static class IntegerWrapperConverter implements AttributeConverter { - @Override - public Integer convertToDatabaseColumn(IntegerWrapper attribute) { - return attribute == null ? null : attribute.getValue(); - } - - @Override - public IntegerWrapper convertToEntityAttribute(Integer dbData) { - return dbData == null ? null : new IntegerWrapper( dbData ); - } - } - - @Converter(autoApply = true) - public static class StringWrapperConverter implements AttributeConverter { - @Override - public String convertToDatabaseColumn(StringWrapper attribute) { - return attribute == null ? null : attribute.getValue(); - } - - @Override - public StringWrapper convertToEntityAttribute(String dbData) { - return dbData == null ? null : new StringWrapper( dbData ); - } - } - - @Converter - public static class PreFixedStringConverter implements AttributeConverter { - @Override - public String convertToDatabaseColumn(String attribute) { - return attribute == null ? null : "VALUE_" + attribute; - } - - @Override - public String convertToEntityAttribute(String dbData) { - return dbData == null ? null : dbData.substring( 6 ); - } - } - - @Entity(name = "EntityConverter") - @Table(name = "entity_converter") - public static class EntityConverter { - @Id - @GeneratedValue - private Integer id; - - private Letter letterOrdinal; - @Enumerated(EnumType.STRING) - private Letter letterString; - - private Numbers numbersImplicit; - @Convert(converter = NumberStringConverter.class) - private Numbers numbersImplicitOverrided; - - private IntegerWrapper integerWrapper; - private StringWrapper stringWrapper; - - @Convert(converter = PreFixedStringConverter.class) - @Column(name = "same_type_converter") - private String sameTypeConverter; - - public Integer getId() { - return id; - } - - public Letter getLetterOrdinal() { - return letterOrdinal; - } - - public void setLetterOrdinal(Letter letterOrdinal) { - this.letterOrdinal = letterOrdinal; - } - - public Letter getLetterString() { - return letterString; - } - - public void setLetterString(Letter letterString) { - this.letterString = letterString; - } - - public Numbers getNumbersImplicit() { - return numbersImplicit; - } - - public void setNumbersImplicit(Numbers numbersImplicit) { - this.numbersImplicit = numbersImplicit; - } - - public Numbers getNumbersImplicitOverrided() { - return numbersImplicitOverrided; - } - - public void setNumbersImplicitOverrided(Numbers numbersImplicitOverrided) { - this.numbersImplicitOverrided = numbersImplicitOverrided; - } - - public IntegerWrapper getIntegerWrapper() { - return integerWrapper; - } - - public void setIntegerWrapper(IntegerWrapper integerWrapper) { - this.integerWrapper = integerWrapper; - } - - public StringWrapper getStringWrapper() { - return stringWrapper; - } - - public void setStringWrapper(StringWrapper stringWrapper) { - this.stringWrapper = stringWrapper; - } - - public String getSameTypeConverter() { - return sameTypeConverter; - } - - public void setSameTypeConverter(String sameTypeConverter) { - this.sameTypeConverter = sameTypeConverter; - } - } - - public static class IntegerWrapper { - private final int value; - - public IntegerWrapper(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - @Override - public String toString() { - return String.format( "IntegerWrapper{value=%d}", value); - } - } - - public static class StringWrapper { - private final String value; - - public StringWrapper(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/ConverterAndLobTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/lob/ConverterAndLobTest.java deleted file mode 100644 index 3382aaa8ef..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/lob/ConverterAndLobTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.test.converter.lob; - -import java.util.Map; - -import org.hibernate.Session; -import org.hibernate.cfg.AvailableSettings; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * @author Steve Ebersole - */ -public class ConverterAndLobTest extends BaseNonConfigCoreFunctionalTestCase { - - @Test - @TestForIssue( jiraKey = "HHH-9615" ) - @SuppressWarnings("unchecked") - public void basicTest() { - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during store... - PostalAreaConverter.clearCounts(); - - Session session = openSession(); - session.getTransaction().begin(); - session.save( new Address( 1, "123 Main St.", null, PostalArea._78729 ) ); - session.getTransaction().commit(); - session.close(); - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(1) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(0) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // test during load... - PostalAreaConverter.clearCounts(); - - session = openSession(); - session.getTransaction().begin(); - Address address = session.get( Address.class, 1 ); - session.getTransaction().commit(); - session.close(); - - assertThat( PostalAreaConverter.toDatabaseCallCount, is(0) ); - assertThat( PostalAreaConverter.toDomainCallCount, is(1) ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // cleanup - session = openSession(); - session.getTransaction().begin(); - session.delete( address ); - session.getTransaction().commit(); - session.close(); - } - - - @Override - protected void addSettings(Map settings) { - super.addSettings( settings ); - settings.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" ); - - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Address.class }; - } - -} diff --git a/hibernate-core/src/test/resources/org/hibernate/test/converter/mixed.xml b/hibernate-core/src/test/resources/org/hibernate/test/converter/mixed.xml index b976ced977..cb39889185 100644 --- a/hibernate-core/src/test/resources/org/hibernate/test/converter/mixed.xml +++ b/hibernate-core/src/test/resources/org/hibernate/test/converter/mixed.xml @@ -10,13 +10,13 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0"> - + - + diff --git a/hibernate-core/src/test/resources/org/hibernate/test/converter/orm.xml b/hibernate-core/src/test/resources/org/hibernate/test/converter/orm.xml index a4982888ef..8eb49f7105 100644 --- a/hibernate-core/src/test/resources/org/hibernate/test/converter/orm.xml +++ b/hibernate-core/src/test/resources/org/hibernate/test/converter/orm.xml @@ -9,5 +9,5 @@ org.hibernate.test.type - + diff --git a/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override.xml b/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override.xml index ba63b4eda6..aac46a78e4 100644 --- a/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override.xml +++ b/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override.xml @@ -11,10 +11,10 @@ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm/orm_2_1.xsd" version="2.1"> - + org.hibernate.jpa.test.convert - + diff --git a/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override2.xml b/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override2.xml index 8ce3a766cf..65f73a3076 100644 --- a/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override2.xml +++ b/hibernate-core/src/test/resources/org/hibernate/test/converter/simple-override2.xml @@ -10,10 +10,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm/orm_2_1.xsd" version="2.1"> - + org.hibernate.jpa.test.convert - + \ No newline at end of file diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/ExceptionHelper.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/ExceptionHelper.java new file mode 100644 index 0000000000..86a8db82be --- /dev/null +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/ExceptionHelper.java @@ -0,0 +1,20 @@ +/* + * 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.testing.orm; + +/** + * @author Steve Ebersole + */ +public class ExceptionHelper { + public static Throwable getRootCause(Throwable error) { + Throwable toProcess = error; + while ( toProcess.getCause() != null ) { + toProcess = toProcess.getCause(); + } + return toProcess; + } +}