spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Converters annotated with @Converter cannot be autowired into

Open Dragas opened this issue 6 years ago • 7 comments

According to #20852, spring framework and hibernate support dependency injection into AttributeConverter<FROM, TO> instances, but only as long as you do not annotate your implementation with @Converter, which is required by JSR-338 chapter 10.6, page 421.

The following stacktrace suggests that Spring ORM still indirectly calls AttributeConverterDefinition, which is deprecated as of Hibernate 5.3

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to instantiate AttributeConverter [lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
	at lt.saltyjuice.dragas.configuration.SigningApplication.main(SigningApplication.java:23)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:558)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.AnnotationException: Unable to instantiate AttributeConverter [lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter]
	at org.hibernate.cfg.AttributeConverterDefinition.instantiateAttributeConverter(AttributeConverterDefinition.java:63)
	at org.hibernate.cfg.AttributeConverterDefinition.from(AttributeConverterDefinition.java:80)
	at org.hibernate.boot.model.process.internal.ScanningCoordinator.applyScanResultsToManagedResources(ScanningCoordinator.java:235)
	at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:82)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:99)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:232)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:167)
	at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:51)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1804)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1741)
	... 22 common frames omitted
Caused by: java.lang.InstantiationException: lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter
	at java.lang.Class.newInstance(Class.java:427)
	at org.hibernate.cfg.AttributeConverterDefinition.instantiateAttributeConverter(AttributeConverterDefinition.java:59)
	... 35 common frames omitted
Caused by: java.lang.NoSuchMethodException: lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	... 36 common frames omitted
java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:558)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to instantiate AttributeConverter [lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
	at lt.saltyjuice.dragas.configuration.SigningApplication.main(SigningApplication.java:23)
	... 6 more
Caused by: org.hibernate.AnnotationException: Unable to instantiate AttributeConverter [lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter]
	at org.hibernate.cfg.AttributeConverterDefinition.instantiateAttributeConverter(AttributeConverterDefinition.java:63)
	at org.hibernate.cfg.AttributeConverterDefinition.from(AttributeConverterDefinition.java:80)
	at org.hibernate.boot.model.process.internal.ScanningCoordinator.applyScanResultsToManagedResources(ScanningCoordinator.java:235)
	at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:82)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:99)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:232)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:167)
	at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:51)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1804)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1741)
	... 22 more
Caused by: java.lang.InstantiationException: lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter
	at java.lang.Class.newInstance(Class.java:427)
	at org.hibernate.cfg.AttributeConverterDefinition.instantiateAttributeConverter(AttributeConverterDefinition.java:59)
	... 35 more
Caused by: java.lang.NoSuchMethodException: lt.saltyjuice.dragas.configuration.AtomicEventContextMapConverter.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	... 36 more

Dragas avatar Nov 11 '19 11:11 Dragas

@Dragas I ran today into the same issue and after a couple of hours I was finally able to resolve it. I had manually configured the LocalContainerEntityManagerFactoryBean. I could resolve the issue after removing the manual creation and configuration of that bean. I just wanted to leave a comment maybe it helps you and others. Good Luck!

TomSchalld avatar Dec 03 '19 15:12 TomSchalld

I don't seem to depend on manually configured LocalContainerEntityManagerFactoryBean but I'll keep it in mind.

Dragas avatar Dec 04 '19 09:12 Dragas

I've had similar issue and resolved this with the SpringBeanContainer

so...

LocalContainerEntityManagerFactoryBean emfb = ...
emfb.getJpaPropertyMap().put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory));

jonseah avatar Jan 02 '20 07:01 jonseah

Still no update on this? I have the same exception for a multi-datasource setup (where you have to create the entity manager yourself).

While I could resolve the problem with @jonseah solution, I think spring should be able to directly cover this?

membersound avatar Dec 09 '20 09:12 membersound

I'm not using LocalContainerEntityManagerFactoryBean in my project and I have the same problem.

nkavian avatar May 06 '21 22:05 nkavian

hi. I have the same exception for a multi-datasource setup. While I could resolve the problem with @jonseah solution but I have the following problem.

first problem : org.springframework.beans.factory.BeanCreationException > Invocation of init method failed; nested exception is org.hibernate.MappingException solve : @jonseah solution. :)

second problem: org.springframework.beans.factory.BeanCreationException > nested exception is org.hibernate.AnnotationException solve: delete @Converter annotation but this solution doesn't seem to work.

question: Another way to solve second problem

haepyung avatar May 11 '21 03:05 haepyung

Hi, I believe I'm also running into this using spring boot 2.7.3.

I try to implement a AttributeConverter to convert an object to JSON using a custom deserialiser which I registered in a object mapper bean. Injecting this object mapper to the AttributeConverter fails -- the constructor is never called.

For now I'll resolve this by building the mapper in a static field on the first access, but this seems hacky to me.

seletz avatar Oct 12 '22 06:10 seletz

Can someone share an example of how to solve it? I need to autowire object from third party package and really stuck in making this make with JPA converter. P.S Not using LocalContainerEntityManagerFactoryBean

tarunwadhwa-paypay avatar Apr 06 '23 06:04 tarunwadhwa-paypay

Spring Framework should remain agnostic at whether Hibernate is configured with SpringBeanContainer. Spring Boot, on the other hand, configures this by default in the meantime. If you are configuring hibernate manually, then you should specify that setting, like any other setting really. If you're using spring boot with the default, it is covered.

snicoll avatar Oct 05 '23 09:10 snicoll