HHH-10308 : Don't make deep copy of property with AttributeConverter if Java type is known to be immutable

This commit is contained in:
Gail Badner 2015-11-19 22:29:14 -08:00
parent 1183a4719d
commit 780c7c2fb6
3 changed files with 30 additions and 5 deletions

View File

@ -9,6 +9,7 @@ package org.hibernate.type.descriptor.converter;
import javax.persistence.AttributeConverter; import javax.persistence.AttributeConverter;
import org.hibernate.type.AbstractSingleColumnStandardBasicType; import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -32,8 +33,9 @@ public class AttributeConverterTypeAdapter<T> extends AbstractSingleColumnStanda
private final Class jdbcType; private final Class jdbcType;
private final AttributeConverter<? extends T,?> attributeConverter; private final AttributeConverter<? extends T,?> attributeConverter;
private final AttributeConverterMutabilityPlanImpl<T> mutabilityPlan; private final MutabilityPlan<T> mutabilityPlan;
@SuppressWarnings("unchecked")
public AttributeConverterTypeAdapter( public AttributeConverterTypeAdapter(
String name, String name,
String description, String description,
@ -49,7 +51,10 @@ public class AttributeConverterTypeAdapter<T> extends AbstractSingleColumnStanda
this.jdbcType = jdbcType; this.jdbcType = jdbcType;
this.attributeConverter = attributeConverter; this.attributeConverter = attributeConverter;
this.mutabilityPlan = new AttributeConverterMutabilityPlanImpl<T>( attributeConverter ); this.mutabilityPlan =
entityAttributeJavaTypeDescriptor.getMutabilityPlan().isMutable() ?
new AttributeConverterMutabilityPlanImpl<T>( attributeConverter ) :
ImmutableMutabilityPlan.INSTANCE;
log.debug( "Created AttributeConverterTypeAdapter -> " + name ); log.debug( "Created AttributeConverterTypeAdapter -> " + name );
} }

View File

@ -122,9 +122,19 @@ public class JavaTypeDescriptorRegistry {
public static class FallbackJavaTypeDescriptor<T> extends AbstractTypeDescriptor<T> { public static class FallbackJavaTypeDescriptor<T> extends AbstractTypeDescriptor<T> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected FallbackJavaTypeDescriptor(Class<T> type) { protected FallbackJavaTypeDescriptor(final Class<T> type) {
// MutableMutabilityPlan would be the "safest" option, but we do not necessarily know how to deepCopy etc... // MutableMutabilityPlan is the "safest" option, but we do not necessarily know how to deepCopy etc...
super( type, ImmutableMutabilityPlan.INSTANCE ); super(
type,
new MutableMutabilityPlan<T>() {
@Override
protected T deepCopyNotNull(T value) {
throw new HibernateException(
"Not known how to deep copy value of type: [" + type.getName() + "]"
);
}
}
);
} }
@Override @Override

View File

@ -14,10 +14,13 @@ import javax.persistence.Id;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -109,6 +112,13 @@ public class DirtyCheckingTest extends BaseNonConfigCoreFunctionalTestCase {
session.close(); session.close();
} }
@Test
public void checkConverterMutabilityPlans() {
final EntityPersister persister = sessionFactory().getEntityPersister( SomeEntity.class.getName() );
assertFalse( persister.getPropertyType( "number" ).isMutable() );
assertTrue( persister.getPropertyType( "name" ).isMutable() );
}
@Override @Override
protected Class[] getAnnotatedClasses() { protected Class[] getAnnotatedClasses() {
return new Class[] {SomeEntity.class}; return new Class[] {SomeEntity.class};