Could not extract ParameterizedType representation of AttributeConverter definition

Description

When custom AttributeConverter has no explicit "implements AttributeConverter" (it is subclass of some base implementation of AttributeConverter) I got exception as below.

When I explicitly add "implements AttributeConverter" everything is ok, so there is easy workaround.

I created test case:
https://github.com/wjtk/mytests-jpa-spring
on branch "hibernate-bug", in class: wkr.testy.jpa.converters.ColorOneLetterConverter.

Exception
Caused by: org.hibernate.AssertionFailure: Could not extract ParameterizedType representation of AttributeConverter definition from AttributeConverter implementation class [wkr.testy.jpa.converters.ColorOneLetterConverter]
at org.hibernate.cfg.AttributeConverterDefinition.extractAttributeConverterParameterizedType(AttributeConverterDefinition.java:94)
at org.hibernate.cfg.AttributeConverterDefinition.<init>(AttributeConverterDefinition.java:52)
at org.hibernate.cfg.Configuration.addAttributeConverter(Configuration.java:2690)
at org.hibernate.cfg.Configuration.addAttributeConverter(Configuration.java:2641)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.buildHibernateConfiguration(EntityManagerFactoryBuilderImpl.java:1129)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:846)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:150)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:67)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:318)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 53 more

Environment

all in test case

Activity

Show:
Wojciech Krak
September 16, 2014, 10:37 PM

Yes, still the same. I've updated test case: https://github.com/wjtk/mytests-jpa-spring (branch: hibernate-bug)

Todd Richmond
February 3, 2015, 12:39 AM
Edited

This issue seems to be a bit more serious. I'm trying to create a generic converter to store arbitrary fields as JSON instead of serialized LOBs. I don't need to be able to query on data in the field object and this makes it much easier to debug because the format will be identical to what goes over the REST API. The problem is that it cannot determine the class for T when T is either a standard or templated class (like List<Foo>)

Hibernate UserTypes have the same issue with templated types, but will work with standard objects. However, that requires creating empty classes to wrap all Lists/Sets/Maps and is Hibernate specific instead of generic JPA

public class JSONAttributeConverter<T> implements AttributeConverter<T, String> {
private final Class<T> clazz;

@SuppressWarnings("unchecked")
public JSONAttributeConverter() {
clazz = (Class<T>) ((ParameterizedType) getClass().
getGenericSuperclass()).getActualTypeArguments()[0];
}

@Override
public String convertToDatabaseColumn(final T object) {
return object == null ? null : new JsonUtility<>(clazz).toString(object);
}

@Override
public T convertToEntityAttribute(final String value) {
return value == null ? null : new JsonUtility<>(clazz).readFromString(
value);
}
}

...

It turns out that moving the implements AttributeConverter out of the template class and into the subclass allows standard objects to work. I still need wrapper classes for templated fields but can at least use JPA conventions and the simpler AttributeConverter interface

public class JSONAttributeConverter<T> {

Svein Baardsen
May 15, 2015, 11:40 AM

I have submitted a fix for this here.

Steve Ebersole
May 20, 2015, 5:29 AM

Thanks ! I will take a look tomorrow

Assignee

Steve Ebersole

Reporter

Wojciech Krak

Fix versions

Labels

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Minor
Configure