HHH-8854 Resolve any TypeVariables to Class or ParameterizedType when
creating AttributeConverterDefinition
This commit is contained in:
parent
b5845138e6
commit
bb2833bafc
|
@ -156,6 +156,7 @@ public class AttributeConverterDefinition {
|
||||||
types.add( clazz.getGenericSuperclass() );
|
types.add( clazz.getGenericSuperclass() );
|
||||||
types.addAll( Arrays.asList( clazz.getGenericInterfaces() ) );
|
types.addAll( Arrays.asList( clazz.getGenericInterfaces() ) );
|
||||||
for ( Type type : types ) {
|
for ( Type type : types ) {
|
||||||
|
type = resolveType( type, base );
|
||||||
if ( ParameterizedType.class.isInstance( type ) ) {
|
if ( ParameterizedType.class.isInstance( type ) ) {
|
||||||
final ParameterizedType parameterizedType = (ParameterizedType) type;
|
final ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||||
if ( AttributeConverter.class.equals( parameterizedType.getRawType() ) ) {
|
if ( AttributeConverter.class.equals( parameterizedType.getRawType() ) ) {
|
||||||
|
@ -171,6 +172,54 @@ public class AttributeConverterDefinition {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Type resolveType(Type target, Type context) {
|
||||||
|
if ( target instanceof ParameterizedType ) {
|
||||||
|
return resolveParameterizedType( (ParameterizedType) target, context );
|
||||||
|
}
|
||||||
|
else if ( target instanceof TypeVariable ) {
|
||||||
|
return resolveTypeVariable( (TypeVariable) target, (ParameterizedType) context );
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ParameterizedType resolveParameterizedType(final ParameterizedType parameterizedType, Type context) {
|
||||||
|
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||||
|
|
||||||
|
final Type[] resolvedTypeArguments = new Type[actualTypeArguments.length];
|
||||||
|
for ( int idx = 0; idx < actualTypeArguments.length; idx++ ) {
|
||||||
|
resolvedTypeArguments[idx] = resolveType( actualTypeArguments[idx], context );
|
||||||
|
}
|
||||||
|
return new ParameterizedType() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type[] getActualTypeArguments() {
|
||||||
|
return resolvedTypeArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getRawType() {
|
||||||
|
return parameterizedType.getRawType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getOwnerType() {
|
||||||
|
return parameterizedType.getOwnerType();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type resolveTypeVariable(TypeVariable typeVariable, ParameterizedType context) {
|
||||||
|
Class clazz = extractClass( context.getRawType() );
|
||||||
|
TypeVariable[] typeParameters = clazz.getTypeParameters();
|
||||||
|
for ( int idx = 0; idx < typeParameters.length; idx++ ) {
|
||||||
|
if ( typeVariable.getName().equals( typeParameters[idx].getName() ) ) {
|
||||||
|
return resolveType( context.getActualTypeArguments()[idx], context );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeVariable;
|
||||||
|
}
|
||||||
|
|
||||||
public AttributeConverter getAttributeConverter() {
|
public AttributeConverter getAttributeConverter() {
|
||||||
return attributeConverter;
|
return attributeConverter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.hibernate.test.type;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
|
||||||
import org.hibernate.cfg.AttributeConverterDefinition;
|
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||||
|
@ -11,7 +13,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the ability to interpret and understand AttributeConverter impls when the base class does not
|
* Test the ability to interpret and understand AttributeConverter impls when the base class does not
|
||||||
* explicitly implement AttributeConverter but implements it via an interface or superclass.
|
* explicitly implement AttributeConverter but implements it via an interface or superclass. This also
|
||||||
|
* involves resolving any TypeVariables to Class or ParameterizedType.
|
||||||
*
|
*
|
||||||
* @author Svein Baardsen
|
* @author Svein Baardsen
|
||||||
*/
|
*/
|
||||||
|
@ -62,4 +65,38 @@ public class AttributeConverterOnSuperclassTest extends BaseUnitTestCase {
|
||||||
assertEquals( String.class, def.getEntityAttributeType() );
|
assertEquals( String.class, def.getEntityAttributeType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class NoopAttributeConverter<T> implements AttributeConverter<T, T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T convertToDatabaseColumn(T attribute) {
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T convertToEntityAttribute(T dbData) {
|
||||||
|
return dbData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StringNoopAttributeConverter extends NoopAttributeConverter<String> {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypeVariableAttributeConverterTypeArguments() {
|
||||||
|
AttributeConverterDefinition def = AttributeConverterDefinition.from( StringNoopAttributeConverter.class );
|
||||||
|
assertEquals( String.class, def.getEntityAttributeType() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ListNoopAttributeConverter<T> extends NoopAttributeConverter<List<T>> {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StringListNoopAttributeConverter extends ListNoopAttributeConverter<String> {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParameterizedTypeWithTypeVariableAttributeConverterTypeArguments() {
|
||||||
|
AttributeConverterDefinition def = AttributeConverterDefinition.from( StringListNoopAttributeConverter.class );
|
||||||
|
assertEquals( List.class, def.getEntityAttributeType() );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue