Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Hibernate 5.3's ManagedBeanRegistry for dependency injection [SPR-16305] #20852

Closed
spring-projects-issues opened this issue Dec 15, 2017 · 6 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Dec 15, 2017

Chris Cranford opened SPR-16305 and commented

Hibernate 5.3 introduces a new service contract called ManagedBeanRegistry.
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/resource/beans/spi/ManagedBeanRegistry.java

This service contract would enable users of Spring to define Spring managed beans for various persistence objects such as Attribute Converters, Event Listeners, and Revision Listeners allowing Hibernate to lookup and use those beans as needed.


Issue Links:

Referenced from: commits 620e83c, c0d4cb5

2 votes, 4 watchers

@spring-projects-issues
Copy link
Collaborator Author

Chris Cranford commented

I would not mind supplying a PR to enable this feature for Spring; however, I wanted to first open a dialog about how Spring would like to see this implemented.

Currently, implementations can supply Hibernate with a service loader extension point, a ServiceContributor, which injects a StandardServiceInitiator implementation in Hibernate allowing us to locate and create various implementations and override default implementations of internal services. This initiator would simply supply Hibernate with spring's specific ManagedBeanRegistry implementation.

Ideally I would prefer to develop a solution that would work for all users who use Hibernate as a persistence layer, regardless of whether they're bootstrapping spring-orm with an EntityManagerFactory or whether they're using the native Hibernate 5 SessionFactory package classes. One idea would be for spring-orm to ship with a ServiceContributor service loader file allowing Hibernate 5.3 to bootstrap that automatically. For prior versions of Hibernate and non-Hibernate providers, this would be ignored.

Does this seem reasonable for you guys or is there another alternative you'd like for me to try and integrate this using?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jul 4, 2018

Juergen Hoeller commented

For a start, Spring's LocalSessionFactoryBuilder provides Hibernate 5.3 BeanContainer support now, and LocalSessionFactoryBean automatically registers its containing BeanFactory as a BeanContainer when Hibernate 5.3 or higher is on the classpath. This goes nicely with #21540 and native Hibernate bootstrapping for JPA.

SpringBeanContainer is currently not public and therefore cannot be used independently, in particular not with Hibernate properties passed through standard JPA configuration via LocalContainerEntityManagerFactoryBean's "jpaProperties". Making it independently available is a bit tricky since the adapter needs access to the containing BeanFactory (which is an independent instance in Spring, not a static or JNDI-shared global setup).

As per #21540, an emerging strategy for specific Hibernate JPA support seems to be LocalSessionFactoryBean-driven bootstrapping as an alternative to LocalContainerEntityManagerFactoryBean for Hibernate 5.2+. There are currently a couple of differences in configuration style that prevent it from being a complete replacement though, so we'll have to reconsider our overall options for standard JPA setup in the 5.1 timeframe.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

SpringBeanContainer is public for custom JPA configuration purposes now, with XML and programmatic examples in its javadoc, e.g.:

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

Next to the above-mentioned support in native Hibernate LocalSessionFactoryBean and LocalSessionFactoryBuilder configuration.

@spring-projects-issues
Copy link
Collaborator Author

Chris Cranford commented

Juergen Hoeller, thanks for the effort to get this support in.  I'm sure users of both our communities will be thrilled.

@Dragas
Copy link

Dragas commented Nov 8, 2019

The issue is still present when you annotate your converter with @Converter, as required by JPA. According to the following stacktarce, 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

@sbrannen
Copy link
Member

sbrannen commented Nov 9, 2019

@Dragas, can you please open a new issue to address your concerns?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants