HHH-14206 Auto-apply converter not applied to primitives

This commit is contained in:
Nathan Xu 2020-08-28 16:42:40 -04:00 committed by Christian Beikov
parent 1cf99c748a
commit 3846001907
2 changed files with 60 additions and 5 deletions

View File

@ -20,6 +20,7 @@ import org.hibernate.boot.model.convert.spi.AutoApplicableConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.annotations.HCANNHelper;
import org.hibernate.internal.util.type.PrimitiveWrapperHelper;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.ResolvedTypeWithMembers;
@ -147,7 +148,11 @@ public class AutoApplicableConverterDescriptorStandardImpl implements AutoApplic
}
private boolean typesMatch(ResolvedType converterDefinedType, ResolvedType checkType) {
if ( !converterDefinedType.getErasedType().isAssignableFrom( checkType.getErasedType() ) ) {
Class<?> erasedCheckType = checkType.getErasedType();
if ( erasedCheckType.isPrimitive() ) {
erasedCheckType = PrimitiveWrapperHelper.getDescriptorByPrimitiveType( erasedCheckType ).getWrapperClass();
}
if ( !converterDefinedType.getErasedType().isAssignableFrom( erasedCheckType ) ) {
return false;
}
@ -180,4 +185,5 @@ public class AutoApplicableConverterDescriptorStandardImpl implements AutoApplic
return true;
}
}

View File

@ -29,8 +29,8 @@ 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.HANACloudColumnStoreDialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HANACloudColumnStoreDialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.internal.ast.tree.JavaConstantNode;
import org.hibernate.internal.util.ConfigHelper;
@ -42,15 +42,16 @@ import org.hibernate.type.BasicType;
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;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.util.ExceptionUtil;
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.junit.Test;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
@ -278,6 +279,36 @@ public class AttributeConverterTest extends BaseUnitTestCase {
}
}
@Test
@TestForIssue( jiraKey = "HHH-14206" )
public void testPrimitiveTypeConverterAutoApplied() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
try {
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();
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() );
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Test
public void testBasicTimestampUsage() {
Configuration cfg = new Configuration();
@ -513,6 +544,24 @@ public class AttributeConverterTest extends BaseUnitTestCase {
}
}
@Entity(name = "T5")
@SuppressWarnings("UnusedDeclaration")
public static class Tester5 {
@Id
private Long id;
private String name;
private int code;
public Tester5() {
}
public Tester5(Long id, String name, int code) {
this.id = id;
this.name = name;
this.code = code;
}
}
// 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;