parent
1caebf7cc6
commit
e04a9bff0d
|
@ -127,11 +127,11 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
|
|||
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<J> implements BasicValue.Resolution<J> {
|
|||
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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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<O,R> implements JpaAttributeConverter<O,R
|
|||
final JavaTypeDescriptorRegistry jtdRegistry = context.getJavaTypeDescriptorRegistry();
|
||||
|
||||
jdbcJtd = jtdRegistry.getDescriptor( jdbcJavaType );
|
||||
domainJtd = jtdRegistry.resolveDescriptor(
|
||||
//noinspection unchecked
|
||||
domainJtd = (JavaTypeDescriptor<O>) jtdRegistry.resolveDescriptor(
|
||||
domainJavaType,
|
||||
() -> RegistryHelper.INSTANCE.createTypeDescriptor( domainJavaType, context.getTypeConfiguration() )
|
||||
() -> RegistryHelper.INSTANCE.createTypeDescriptor(
|
||||
domainJavaType,
|
||||
() -> {
|
||||
final Class<? extends AttributeConverter<O, R>> converterClass = attributeConverterBean.getBeanClass();
|
||||
final MutabilityPlan<Object> mutabilityPlan = RegistryHelper.INSTANCE.determineMutabilityPlan(
|
||||
converterClass,
|
||||
context.getTypeConfiguration()
|
||||
);
|
||||
|
||||
if ( mutabilityPlan != null ) {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
return new AttributeConverterMutabilityPlanImpl<>( this, true );
|
||||
},
|
||||
context.getTypeConfiguration()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,11 +168,16 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T> {
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<SqmParameter, List<List<JdbcParameter>>> jdbcParamMap = jdbcParamXref.get( queryParam );
|
||||
for ( SqmParameter sqmParameter : sqmParameters ) {
|
||||
sqm_params: for ( SqmParameter sqmParameter : sqmParameters ) {
|
||||
final List<List<JdbcParameter>> 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<JdbcParameter> 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<JdbcParameter> 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<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
|
||||
|
|
|
@ -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<T extends Statement> extends Base
|
|||
popProcessingStateStack();
|
||||
}
|
||||
|
||||
inferableTypeAccessStack.push( assignedPathInterpretation::getExpressionType );
|
||||
inferrableTypeAccessStack.push( assignedPathInterpretation::getExpressionType );
|
||||
|
||||
final List<ColumnReference> valueColumnReferences = new ArrayList<>();
|
||||
pushProcessingState(
|
||||
|
@ -703,7 +705,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
finally {
|
||||
popProcessingStateStack();
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2046,8 +2048,10 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
|
||||
@Override
|
||||
public Expression visitLiteral(SqmLiteral<?> literal) {
|
||||
final Supplier<MappingModelExpressable> 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<T extends Statement> 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<T extends Statement> extends Base
|
|||
nodeType );
|
||||
|
||||
if ( valueMapping == null ) {
|
||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferableTypeAccessStack.getCurrent();
|
||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
|
||||
if ( currentExpressableSupplier != null ) {
|
||||
return currentExpressableSupplier.get();
|
||||
}
|
||||
|
@ -2149,30 +2191,62 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<MappingModelExpressable> currentExpressableSupplier = inferableTypeAccessStack.getCurrent();
|
||||
final Supplier<MappingModelExpressable> 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<MappingModelExpressable> currentExpressableSupplier = inferableTypeAccessStack.getCurrent();
|
||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
|
||||
if ( currentExpressableSupplier != null ) {
|
||||
return currentExpressableSupplier.get();
|
||||
}
|
||||
|
@ -2196,7 +2270,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<MappingModelExpressable> currentExpressableSupplier = inferableTypeAccessStack.getCurrent();
|
||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
|
||||
if ( currentExpressableSupplier != null ) {
|
||||
final MappingModelExpressable inferredMapping = currentExpressableSupplier.get();
|
||||
if ( inferredMapping != null ) {
|
||||
|
@ -2226,7 +2300,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
throw new ConversionException( "Could not determine ValueMapping for SqmParameter: " + sqmParameter );
|
||||
}
|
||||
|
||||
protected final Stack<Supplier<MappingModelExpressable>> inferableTypeAccessStack = new StandardStack<>(
|
||||
protected final Stack<Supplier<MappingModelExpressable>> inferrableTypeAccessStack = new StandardStack<>(
|
||||
() -> null
|
||||
);
|
||||
|
||||
|
@ -2286,12 +2360,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> extends Base
|
|||
lhs = (Expression) predicate.getLeftHandExpression().accept( this );
|
||||
}
|
||||
finally {
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
return new InSubQueryPredicate(
|
||||
|
@ -3403,24 +3485,24 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> extends Base
|
|||
upperBound = (Expression) predicate.getUpperBound().accept( this );
|
||||
}
|
||||
finally {
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
return new BetweenPredicate(
|
||||
|
@ -3593,7 +3675,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> extends Base
|
|||
}
|
||||
}
|
||||
finally {
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
return inPredicate;
|
||||
|
@ -3632,7 +3714,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
(Expression) sqmPredicate.getTestExpression().accept( this )
|
||||
);
|
||||
|
||||
inferableTypeAccessStack.push(
|
||||
inferrableTypeAccessStack.push(
|
||||
() -> determineValueMapping( sqmPredicate.getTestExpression() )
|
||||
);
|
||||
|
||||
|
@ -3654,7 +3736,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
}
|
||||
finally {
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
return inListPredicate;
|
||||
|
@ -3674,7 +3756,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
(Expression) sqmPredicate.getTestExpression().accept( this )
|
||||
);
|
||||
|
||||
inferableTypeAccessStack.push(
|
||||
inferrableTypeAccessStack.push(
|
||||
() -> determineValueMapping( sqmPredicate.getTestExpression() )
|
||||
);
|
||||
|
||||
|
@ -3699,7 +3781,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
}
|
||||
finally {
|
||||
inferableTypeAccessStack.pop();
|
||||
inferrableTypeAccessStack.pop();
|
||||
}
|
||||
|
||||
return inListPredicate;
|
||||
|
|
|
@ -487,6 +487,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> 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<T extends JdbcOperation> implemen
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (T) jdbcOperation;
|
||||
}
|
||||
finally {
|
||||
|
@ -2437,9 +2439,12 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> 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 );
|
||||
|
|
|
@ -35,16 +35,8 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
|
|||
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
|
||||
|
|
|
@ -224,7 +224,7 @@ public abstract class AbstractStandardBasicType<T>
|
|||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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<T> extends AbstractSingleColumnStanda
|
|||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(Object one, Object another) {
|
||||
//noinspection unchecked
|
||||
return ( (JavaTypeDescriptor<Object>) getDomainJtd() ).areEqual( one, another );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 <J> JavaTypeDescriptor<J> resolveDescriptor(Type javaType) {
|
||||
return resolveDescriptor(
|
||||
javaType,
|
||||
|
@ -148,6 +139,20 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
|
|||
|
||||
return RegistryHelper.INSTANCE.createTypeDescriptor(
|
||||
javaTypeClass,
|
||||
() -> {
|
||||
final MutabilityPlan<J> determinedPlan = RegistryHelper.INSTANCE.determineMutabilityPlan( javaType, typeConfiguration );
|
||||
if ( determinedPlan != null ) {
|
||||
return determinedPlan;
|
||||
}
|
||||
|
||||
return new MutableMutabilityPlan<J>() {
|
||||
@Override
|
||||
protected J deepCopyNotNull(J value) {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 <J> JavaTypeDescriptor<J> createTypeDescriptor(Type javaType, TypeConfiguration typeConfiguration) {
|
||||
public <J> JavaTypeDescriptor<J> createTypeDescriptor(
|
||||
Type javaType,
|
||||
Supplier<MutabilityPlan<J>> fallbackMutabilityPlanResolver,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return createTypeDescriptor(
|
||||
javaType,
|
||||
(javaTypeClass) -> {
|
||||
if ( javaTypeClass.isAnnotationPresent( Immutable.class ) ) {
|
||||
return ImmutableMutabilityPlan.INSTANCE;
|
||||
MutabilityPlan<J> mutabilityPlan = determineMutabilityPlan( javaType, typeConfiguration );
|
||||
if ( mutabilityPlan == null ) {
|
||||
mutabilityPlan = fallbackMutabilityPlanResolver.get();
|
||||
}
|
||||
|
||||
if ( javaTypeClass.isAnnotationPresent( Mutability.class ) ) {
|
||||
final Mutability annotation = javaTypeClass.getAnnotation( Mutability.class );
|
||||
final Class<? extends MutabilityPlan<?>> planClass = annotation.value();
|
||||
final ManagedBeanRegistry managedBeanRegistry = typeConfiguration
|
||||
.getServiceRegistry()
|
||||
.getService( ManagedBeanRegistry.class );
|
||||
final ManagedBean<? extends MutabilityPlan<?>> planBean = managedBeanRegistry.getBean( planClass );
|
||||
return (MutabilityPlan<J>) planBean.getBeanInstance();
|
||||
}
|
||||
|
||||
return ImmutableMutabilityPlan.INSTANCE;
|
||||
return mutabilityPlan;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <J> JavaTypeDescriptor<J> createTypeDescriptor(
|
||||
public <J> MutabilityPlan<J> determineMutabilityPlan(Type javaType, TypeConfiguration typeConfiguration) {
|
||||
final Class<J> 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<? extends MutabilityPlan<?>> planClass = annotation.value();
|
||||
final ManagedBeanRegistry managedBeanRegistry = typeConfiguration
|
||||
.getServiceRegistry()
|
||||
.getService( ManagedBeanRegistry.class );
|
||||
final ManagedBean<? extends MutabilityPlan<?>> planBean = managedBeanRegistry.getBean( planClass );
|
||||
return (MutabilityPlan<J>) planBean.getBeanInstance();
|
||||
}
|
||||
|
||||
if ( javaTypeClass.isEnum() ) {
|
||||
return ImmutableMutabilityPlan.INSTANCE;
|
||||
}
|
||||
|
||||
if ( javaTypeClass.isPrimitive() ) {
|
||||
return ImmutableMutabilityPlan.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Serializable.class.isAssignableFrom( javaTypeClass ) ) {
|
||||
return (MutabilityPlan<J>) SerializableTypeDescriptor.SerializableMutabilityPlan.INSTANCE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <J> JavaTypeDescriptor<J> createTypeDescriptor(
|
||||
Type javaType,
|
||||
Function<Class<J>,MutabilityPlan<J>> mutabilityPlanResolver) {
|
||||
final Class<J> javaTypeClass;
|
||||
if ( javaType instanceof Class<?> ) {
|
||||
javaTypeClass = (Class<J>) javaType;
|
||||
}
|
||||
else {
|
||||
final ParameterizedType parameterizedType = (ParameterizedType) javaType;
|
||||
javaTypeClass = (Class<J>) parameterizedType.getRawType();
|
||||
}
|
||||
final Class<J> javaTypeClass = determineJavaTypeClass( javaType );
|
||||
|
||||
if ( javaTypeClass.isEnum() ) {
|
||||
// enums are unequivocally immutable
|
||||
|
@ -87,4 +106,16 @@ public class RegistryHelper {
|
|||
|
||||
return new JavaTypeDescriptorBasicAdaptor<>( javaTypeClass, plan );
|
||||
}
|
||||
|
||||
private <J> Class<J> determineJavaTypeClass(Type javaType) {
|
||||
final Class<J> javaTypeClass;
|
||||
if ( javaType instanceof Class<?> ) {
|
||||
javaTypeClass = (Class<J>) javaType;
|
||||
}
|
||||
else {
|
||||
final ParameterizedType parameterizedType = (ParameterizedType) javaType;
|
||||
javaTypeClass = (Class<J>) parameterizedType.getRawType();
|
||||
}
|
||||
return javaTypeClass;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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<BlowsUpConverter> 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<Instant, Timestamp> {
|
||||
@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() );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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() );
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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(
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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<TestEntity> query = session.createQuery( qryStr, TestEntity.class );
|
||||
query.setParameter( "ts", new DateAttribute( System.currentTimeMillis() ), TemporalType.TIMESTAMP );
|
||||
final Stream<TestEntity> 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<DateAttribute, Date> {
|
||||
|
||||
@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() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
* 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;
|
|
@ -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;
|
|
@ -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<String, ?> 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<String, ?> 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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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.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" )
|
|
@ -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.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();
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<Color>();
|
||||
customer.set.add(Color.RED);
|
||||
customer.set.add(Color.GREEN);
|
||||
customer.set.add(Color.BLUE);
|
||||
customer.map = new HashMap<Color, Status>();
|
||||
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
|
|
@ -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.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 {
|
|
@ -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.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()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<List<String>, Integer> {
|
||||
@Override
|
||||
public Integer convertToDatabaseColumn(List<String> attribute) {
|
||||
return attribute.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> convertToEntityAttribute(Integer dbData) {
|
||||
return new ArrayList<String>(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<List<String>, Integer> {
|
||||
@Override
|
||||
public Integer convertToDatabaseColumn(List<String> attribute) {
|
||||
return attribute.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> convertToEntityAttribute(Integer dbData) {
|
||||
return new ArrayList<String>(dbData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<String, Long> {
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<EntityConverter> 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<Numbers, Integer> {
|
||||
@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<Numbers, String> {
|
||||
@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<IntegerWrapper, Integer> {
|
||||
@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<StringWrapper, String> {
|
||||
@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<String, String> {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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.map;
|
||||
package org.hibernate.orm.test.mapping.converted.converter.map;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
|
@ -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.map;
|
||||
package org.hibernate.orm.test.mapping.converted.converter.map;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
|
@ -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.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" )
|
|
@ -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.map;
|
||||
package org.hibernate.orm.test.mapping.converted.converter.map;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -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.map;
|
||||
package org.hibernate.orm.test.mapping.converted.converter.map;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<TestEntity> query = session.createQuery(
|
||||
"SELECT e FROM TestEntity e WHERE e.date <= :ts",
|
||||
TestEntity.class
|
||||
).setParameter( "ts", new DateAttribute( System.currentTimeMillis() ), TemporalType.TIMESTAMP );
|
||||
|
||||
final Stream<TestEntity> 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<DateAttribute, Date> {
|
||||
|
||||
@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() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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<String, ?> 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<String, ?> 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 };
|
||||
}
|
||||
|
||||
}
|
|
@ -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 };
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<Numbers, Integer> {
|
||||
@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<Numbers, String> {
|
||||
@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<IntegerWrapper, Integer> {
|
||||
@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<StringWrapper, String> {
|
||||
@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<String, String> {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 };
|
||||
}
|
||||
|
||||
}
|
|
@ -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">
|
||||
|
||||
<!-- Intended for use in org.hibernate.test.converter.XmlWithExplicitConvertAnnotationsTest -->
|
||||
<!-- Intended for use in org.hibernate.orm.test.mapping.converted.converter.XmlWithExplicitConvertAnnotationsTest -->
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
|
||||
<entity-listeners>
|
||||
<entity-listener class="org.hibernate.test.converter.XmlWithExplicitConvertAnnotationsTest$TestEntityListener"/>
|
||||
<entity-listener class="org.hibernate.orm.test.mapping.converted.converter.XmlWithExplicitConvertAnnotationsTest$TestEntityListener"/>
|
||||
</entity-listeners>
|
||||
|
||||
</persistence-unit-defaults>
|
||||
|
|
|
@ -9,5 +9,5 @@
|
|||
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
|
||||
version="2.1">
|
||||
<package>org.hibernate.test.type</package>
|
||||
<converter class="org.hibernate.test.converter.StringClobConverter" auto-apply="true"/>
|
||||
<converter class="org.hibernate.orm.test.mapping.converted.converter.StringClobConverter" auto-apply="true"/>
|
||||
</entity-mappings>
|
||||
|
|
|
@ -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">
|
||||
|
||||
<!-- Intended for use in org.hibernate.test.converter.SimpleXmlOverriddenTest -->
|
||||
<!-- Intended for use in org.hibernate.orm.test.mapping.converted.converter.SimpleXmlOverriddenTest -->
|
||||
|
||||
<package>org.hibernate.jpa.test.convert</package>
|
||||
<entity class="org.hibernate.test.converter.SimpleXmlOverriddenTest$TheEntity">
|
||||
<entity class="org.hibernate.orm.test.mapping.converted.converter.SimpleXmlOverriddenTest$TheEntity">
|
||||
<attributes>
|
||||
<basic name="it">
|
||||
<convert disable-conversion="true" />
|
||||
|
|
|
@ -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">
|
||||
<!-- Intended for use in org.hibernate.test.converter.SimpleXmlOverriddenTest -->
|
||||
<!-- Intended for use in org.hibernate.orm.test.mapping.converted.converter.SimpleXmlOverriddenTest -->
|
||||
|
||||
<package>org.hibernate.jpa.test.convert</package>
|
||||
<entity class="org.hibernate.test.converter.SimpleXmlOverriddenTest$TheEntity2">
|
||||
<entity class="org.hibernate.orm.test.mapping.converted.converter.SimpleXmlOverriddenTest$TheEntity2">
|
||||
<convert attribute-name="it" disable-conversion="true"/>
|
||||
</entity>
|
||||
</entity-mappings>
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue