I was using HibernateJpaSessionFactoryBean
in Spring Boot 1.5.x to get a session factory bean for my sessions. Since that's deprecated now, I'm trying to use the session factory by unwrapping in an EntityManagerFactory. But, I can't get EntityManagerFactory to be autowired. There's no bean defining it.
What do I need to do to wire in an EntityManagerFactory? entityManagerFactory remains null.
/**
* A class to hold necessary data access beans.
*/
@Configuration
@EnableTransactionManagement
public class DataBeans {
@Autowired
private EntityManagerFactory entityManagerFactory;
/**
* This bean needs to be wired in so that a SessionFactory can be wired in to other data access beans.
*
* @return a session factory bean
*/
@Bean
public SessionFactory sessionFactoryProvider() {
return entityManagerFactory.unwrap(SessionFactory.class);
}
}
@SpringBootApplication
public class AppBootMain {
public static void main(String[] args) {
SpringApplication.run(AppBootMain.class, args);
}
}
application.properties:
spring.datasource.driverClassName=org.hsqldb.jdbc.JDBCDriver
spring.datasource.url=jdbc:hsqldb:mem:student_db
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create-drop
# this ensures that a session factory bean is available
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
Note: i tried changing the current_session_context_class
to specify hibernate5 in the package, but no success.
error running bootRun: ```
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataBeans': Unsatisfied dependency expressed through field 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactoryProvider' defined in class path resource [org/webapp/example/school/data/repository/DataBeans.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Circular reference involving containing bean 'dataBeans' - consider declaring the factory method as static for independence from its containing instance. Factory method 'sessionFactoryProvider' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1348)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$94/681094281.getObject(Unknown Source)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
at org.webapp.example.school.AppBootMain.main(AppBootMain.java:27)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactoryProvider' defined in class path resource [org/webapp/example/school/data/repository/DataBeans.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Circular reference involving containing bean 'dataBeans' - consider declaring the factory method as static for independence from its containing instance. Factory method 'sessionFactoryProvider' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1254)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$94/681094281.getObject(Unknown Source)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584)
... 20 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Circular reference involving containing bean 'dataBeans' - consider declaring the factory method as static for independence from its containing instance. Factory method 'sessionFactoryProvider' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
... 33 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.webapp.example.school.data.repository.DataBeans.sessionFactoryProvider(DataBeans.java:30)
at org.webapp.example.school.data.repository.DataBeans$$EnhancerBySpringCGLIB$$ebde0844.CGLIB$sessionFactoryProvider$0(<generated>)
at org.webapp.example.school.data.repository.DataBeans$$EnhancerBySpringCGLIB$$ebde0844$$FastClassBySpringCGLIB$$f2417c25.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361)
at org.webapp.example.school.data.repository.DataBeans$$EnhancerBySpringCGLIB$$ebde0844.sessionFactoryProvider(<generated>)
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:483)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 34 common frames omitted
> Task :bootRun FAILED
I tried putting EntityManagerFactory as a paraemter to the bean method that creatrs teh session factory, but it failed due to circular dependency.
@Bean
public SessionFactory sessionFactoryProvider(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.unwrap(SessionFactory.class);
}
Hibernate SessionFactory is an interface. It can be created through providing objects of Configuration. This will contain all the database property details which are pulled from either hibernate. properties file or hibernate.
Spring 5x is compatible with hibernate 4x unless you are using it as an implementation of JPA which might not be compatible. A suggestion would be using the latest hibernate.
You would need one SessionFactory object per database using a separate configuration file. So, if you are using multiple databases, then you would have to create multiple SessionFactory objects.
I encountered the same problem when upgrade from 1.5 to 2.1.3 and resolved by getting the Session / SessionFactory in the Dao class instead of autowire when spring init.
Following is an example:
@Repository
@Transactional
public class XXXDao {
@Autowired
private EntityManager entityManager;
private Session getSession() {
return entityManager.unwrap(Session.class);
}
...
}
If you really need the SessionFactory, use following coding and beware that the you might need to handle the transaction manually.
@Repository
public class XXXDao {
@Autowired
private EntityManagerFactory entityManagerFactory;
private SessionFactory getSessionFactory() {
return entityManagerFactory.unwrap(SessionFactory.class);
}
...
}
I would suggest you check also the Spring boot hibernate no transaction is in progress for the transaction issue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With