[英]BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Circular reference involving containing bean
I use an example from internet, then try to upgrade from Spring Boot 1.5.10.RELEASE to 2.0.0.RC1. 我使用来自互联网的示例,然后尝试从Spring Boot 1.5.10.RELEASE升级到2.0.0.RC1。 The application works ok with Spring Boot version 1.5.10.RELEASE, but it has error with version 2.0.0.RC1.
该应用程序可以在Spring Boot版本1.5.10.RELEASE上正常工作,但是在版本2.0.0.RC1上却有错误。
File pom.xml 文件pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring_boot_hibernate</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<start-class>spring-boot-example.Application</start-class>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!--<version>1.5.10.RELEASE</version>-->
<version>2.0.0.RC1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-repo</id>
<name>Spring Repository</name>
<url>https://repo.spring.io/release</url>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
File application.properties 文件application.properties
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/vy
spring.datasource.username=root
spring.datasource.password=123456
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
File BeanConfig.java 文件BeanConfig.java
package com.example;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManagerFactory;
@Configuration
public class BeanConfig {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Bean
public SessionFactory getSessionFactory() {
if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
throw new NullPointerException("factory is not a hibernate factory");
}
return entityManagerFactory.unwrap(SessionFactory.class);
}
}
The error happen at line: 错误发生在以下行:
if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
File UserController.java 文件UserController.java
package com.example.controller;
import com.example.model.UserDetails;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ResponseEntity<List<UserDetails>> userDetails() {
List<UserDetails> userDetails = userService.getUserDetails();
return new ResponseEntity<List<UserDetails>>(userDetails, HttpStatus.OK);
}
}
File UserDaoImpl.java 文件UserDaoImpl.java
package com.example.dao.impl;
import com.example.dao.UserDao;
import com.example.model.UserDetails;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
public List<UserDetails> getUserDetails() {
Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
return criteria.list();
}
}
File UserDao.java 文件UserDao.java
package com.example.dao;
import com.example.model.UserDetails;
import java.util.List;
public interface UserDao {
List<UserDetails> getUserDetails();
}
File UserDetails.java 文件UserDetails.java
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table
public class UserDetails {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column
private String firstName;
@Column
private String lastName;
@Column
private String email;
@Column
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
File UserServiceImpl.java 文件UserServiceImpl.java
package com.example.service.impl;
import com.example.dao.UserDao;
import com.example.model.UserDetails;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public List<UserDetails> getUserDetails() {
return userDao.getUserDetails();
}
}
Error 错误
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:49901,suspend=y,server=n --illegal-access=warn -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=49900 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:/Users/donhuvy/Library/Caches/IntelliJIdea2017.3/captureAgent/debugger-...
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/Users/donhuvy/.m2/repository/org/springframework/spring-core/5.0.3.RELEASE/spring-core-5.0.3.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
2018-02-20 07:56:04.273 INFO 1944 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$1e62766c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
.... 2018-02-20 07:56:04.538 INFO 1944 --- [ main]
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-02-20 07:56:04.848 ERROR 1944 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanConfig': Unsatisfied dependency expressed through field 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getSessionFactory' defined in class path resource [com/example/BeanConfig.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 'beanConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getSessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:138) ~[spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RC1.jar:2.0.0.RC1]
at com.example.Application.main(Application.java:10) [classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getSessionFactory' defined in class path resource [com/example/BeanConfig.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 'beanConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getSessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Circular reference involving containing bean 'beanConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getSessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
... 31 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.example.BeanConfig.getSessionFactory(BeanConfig.java:18) ~[classes/:na]
at com.example.BeanConfig$$EnhancerBySpringCGLIB$$54b5def4.CGLIB$getSessionFactory$0(<generated>) ~[classes/:na]
at com.example.BeanConfig$$EnhancerBySpringCGLIB$$54b5def4$$FastClassBySpringCGLIB$$bcb3b797.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at com.example.BeanConfig$$EnhancerBySpringCGLIB$$54b5def4.getSessionFactory(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.3.RELEASE.jar:5.0.3.RELEASE]
... 32 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:49901', transport: 'socket'
Process finished with exit code 1
How to fix it? 如何解决?
In BeanConfig
, you should inject the JPA EntityManager
via @PersistenceUnit
, not @Autowired
. 在
BeanConfig
,应该通过@PersistenceUnit
而不是@Autowired
注入JPA EntityManager
。
And remove the getSessionFactory
since the Hibernate SessionFactory is already created internally and you can always unwrap the EntityManagerFactory
. 并删除
getSessionFactory
因为Hibernate SessionFactory已在内部创建,您可以随时解开EntityManagerFactory
。
So, it should look like this: 因此,它应如下所示:
@Configuration
public class BeanConfig {
@PersistenceUnit
EntityManagerFactory emf;
}
File BeanConfig.java
文件
BeanConfig.java
package com.example;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
@Configuration
public class BeanConfig {
@PersistenceUnit
EntityManagerFactory entityManagerFactory;
@Bean
public SessionFactory getSessionFactory() {
if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
throw new NullPointerException("factory is not a hibernate factory");
}
return entityManagerFactory.unwrap(SessionFactory.class);
}
}
An example about using method getSessionFactory
有关使用方法
getSessionFactory
的示例
package com.example.dao.impl;
import com.example.dao.UserDao;
import com.example.model.UserDetails;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
public List<UserDetails> getUserDetails() {
Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
return criteria.list();
}
}
(It is a working example with Hibernate 5.2.13.Final, Spring Boot 2.0.0.RC2, and Java 9.0.4) (这是Hibernate 5.2.13.Final,Spring Boot 2.0.0.RC2和Java 9.0.4的工作示例)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.