Skip to content

Commit b584513

Browse files
Sveinsebersole
authored andcommitted
HHH-8854 Create AttributeConverterDefinition even if AttributeConverter
is only implemented via superclass or interface
1 parent 1812bb2 commit b584513

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/AttributeConverterDefinition.java

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
import java.lang.reflect.ParameterizedType;
1010
import java.lang.reflect.Type;
1111
import java.lang.reflect.TypeVariable;
12+
import java.util.ArrayList;
13+
import java.util.Arrays;
14+
import java.util.List;
15+
1216
import javax.persistence.AttributeConverter;
1317
import javax.persistence.Converter;
1418

1519
import org.hibernate.AnnotationException;
1620
import org.hibernate.AssertionFailure;
17-
1821
import org.jboss.logging.Logger;
1922

2023
/**
@@ -109,6 +112,12 @@ public AttributeConverterDefinition(AttributeConverter attributeConverter, boole
109112

110113
final Class attributeConverterClass = attributeConverter.getClass();
111114
final ParameterizedType attributeConverterSignature = extractAttributeConverterParameterizedType( attributeConverterClass );
115+
if ( attributeConverterSignature == null ) {
116+
throw new AssertionFailure(
117+
"Could not extract ParameterizedType representation of AttributeConverter definition " +
118+
"from AttributeConverter implementation class [" + attributeConverterClass.getName() + "]"
119+
);
120+
}
112121

113122
if ( attributeConverterSignature.getActualTypeArguments().length < 2 ) {
114123
throw new AnnotationException(
@@ -140,20 +149,26 @@ public AttributeConverterDefinition(AttributeConverter attributeConverter, boole
140149
}
141150
}
142151

143-
private ParameterizedType extractAttributeConverterParameterizedType(Class attributeConverterClass) {
144-
for ( Type type : attributeConverterClass.getGenericInterfaces() ) {
145-
if ( ParameterizedType.class.isInstance( type ) ) {
146-
final ParameterizedType parameterizedType = (ParameterizedType) type;
147-
if ( AttributeConverter.class.equals( parameterizedType.getRawType() ) ) {
152+
private ParameterizedType extractAttributeConverterParameterizedType(Type base) {
153+
if ( base != null ) {
154+
Class clazz = extractClass( base );
155+
List<Type> types = new ArrayList<Type>();
156+
types.add( clazz.getGenericSuperclass() );
157+
types.addAll( Arrays.asList( clazz.getGenericInterfaces() ) );
158+
for ( Type type : types ) {
159+
if ( ParameterizedType.class.isInstance( type ) ) {
160+
final ParameterizedType parameterizedType = (ParameterizedType) type;
161+
if ( AttributeConverter.class.equals( parameterizedType.getRawType() ) ) {
162+
return parameterizedType;
163+
}
164+
}
165+
ParameterizedType parameterizedType = extractAttributeConverterParameterizedType( type );
166+
if ( parameterizedType != null ) {
148167
return parameterizedType;
149168
}
150169
}
151170
}
152-
153-
throw new AssertionFailure(
154-
"Could not extract ParameterizedType representation of AttributeConverter definition " +
155-
"from AttributeConverter implementation class [" + attributeConverterClass.getName() + "]"
156-
);
171+
return null;
157172
}
158173

159174
public AttributeConverter getAttributeConverter() {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.hibernate.test.type;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import javax.persistence.AttributeConverter;
6+
7+
import org.hibernate.cfg.AttributeConverterDefinition;
8+
import org.hibernate.testing.TestForIssue;
9+
import org.hibernate.testing.junit4.BaseUnitTestCase;
10+
import org.junit.Test;
11+
12+
/**
13+
* Test the ability to interpret and understand AttributeConverter impls when the base class does not
14+
* explicitly implement AttributeConverter but implements it via an interface or superclass.
15+
*
16+
* @author Svein Baardsen
17+
*/
18+
@TestForIssue(jiraKey = "HHH-8854")
19+
public class AttributeConverterOnSuperclassTest extends BaseUnitTestCase {
20+
21+
public static class StringIntegerAttributeConverter implements AttributeConverter<String, Integer> {
22+
23+
@Override
24+
public Integer convertToDatabaseColumn(String attribute) {
25+
return Integer.valueOf( attribute );
26+
}
27+
28+
@Override
29+
public String convertToEntityAttribute(Integer dbData) {
30+
return String.valueOf( dbData );
31+
}
32+
}
33+
34+
public static class StringIntegerConverterSubclass extends StringIntegerAttributeConverter {
35+
}
36+
37+
@Test
38+
public void testAttributeConverterOnSuperclass() {
39+
AttributeConverterDefinition def = AttributeConverterDefinition.from( StringIntegerConverterSubclass.class );
40+
assertEquals( String.class, def.getEntityAttributeType() );
41+
}
42+
43+
public interface StringLongAttributeConverter extends AttributeConverter<String, Long> {
44+
}
45+
46+
public static class StringLongAttributeConverterImpl implements StringLongAttributeConverter {
47+
48+
@Override
49+
public Long convertToDatabaseColumn(String attribute) {
50+
return Long.valueOf( attribute );
51+
}
52+
53+
@Override
54+
public String convertToEntityAttribute(Long dbData) {
55+
return String.valueOf( dbData );
56+
}
57+
}
58+
59+
@Test
60+
public void testAttributeConverterOnInterface() {
61+
AttributeConverterDefinition def = AttributeConverterDefinition.from( StringLongAttributeConverterImpl.class );
62+
assertEquals( String.class, def.getEntityAttributeType() );
63+
}
64+
65+
}

0 commit comments

Comments
 (0)