/* * 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.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; 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; 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 static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; /** * Test the ability to interpret and understand AttributeConverter impls which * use parameterized types as one of (typically the "attribute type") its parameter types. * * @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); } } @Test @TestForIssue(jiraKey = "HHH-8804") public void testGenericTypeParameters() { AttributeConverterDefinition def = AttributeConverterDefinition.from( CustomAttributeConverter.class ); assertEquals( List.class, def.getEntityAttributeType() ); } @Test @TestForIssue( jiraKey = "HHH-10050" ) public void testNestedTypeParameterAutoApplication() { final Metadata metadata = new MetadataSources( ssr ) .addAnnotatedClass( SampleEntity.class ) .getMetadataBuilder() .applyAttributeConverter( IntegerListConverter.class ) .applyAttributeConverter( StringListConverter.class ) .build(); // lets make sure the auto-apply converters were applied properly... PersistentClass pc = metadata.getEntityBinding( SampleEntity.class.getName() ); { Property prop = pc.getProperty( "someStrings" ); AttributeConverterTypeAdapter type = assertTyping( AttributeConverterTypeAdapter.class, prop.getType() ); assertTyping( StringListConverter.class, type.getAttributeConverter() ); } { Property prop = pc.getProperty( "someIntegers" ); AttributeConverterTypeAdapter type = assertTyping( AttributeConverterTypeAdapter.class, prop.getType() ); assertTyping( IntegerListConverter.class, type.getAttributeConverter() ); } } @Entity public static class SampleEntity { @Id private Integer id; private List<String> someStrings; private List<Integer> someIntegers; } @Converter( autoApply = true ) public static class IntegerListConverter implements AttributeConverter<List<Integer>,String> { @Override public String convertToDatabaseColumn(List<Integer> attribute) { if ( attribute == null || attribute.isEmpty() ) { return null; } else { return StringHelper.join( ", ", attribute ); } } @Override public List<Integer> convertToEntityAttribute(String dbData) { if ( dbData == null ) { return null; } dbData = dbData.trim(); if ( dbData.length() == 0 ) { return null; } final List<Integer> integers = new ArrayList<Integer>(); final StringTokenizer tokens = new StringTokenizer( dbData, "," ); while ( tokens.hasMoreTokens() ) { integers.add( Integer.valueOf( tokens.nextToken() ) ); } return integers; } } @Converter( autoApply = true ) public static class StringListConverter implements AttributeConverter<List<String>,String> { @Override public String convertToDatabaseColumn(List<String> attribute) { if ( attribute == null || attribute.isEmpty() ) { return null; } else { return StringHelper.join( ", ", attribute ); } } @Override public List<String> convertToEntityAttribute(String dbData) { if ( dbData == null ) { return null; } dbData = dbData.trim(); if ( dbData.length() == 0 ) { return null; } final List<String> strings = new ArrayList<String>(); final StringTokenizer tokens = new StringTokenizer( dbData, "," ); while ( tokens.hasMoreTokens() ) { strings.add( tokens.nextToken() ); } return strings; } } }