【发布时间】:2018-09-21 17:38:31
【问题描述】:
我对新的 Spring Boot 版本 2.0.0 有疑问。 我需要创建 SessionFactory bean,为此我需要 Spring 来注入 EntityManager。
package cz.moravec;
import cz.moravec.provisioning.Provisioner;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
@SpringBootApplication
@EntityScan("cz.moravec.data")
public class Main {
// @Bean
// public CountryDao countryDao() {
// return new CountryDao();
// }
//
// @Bean
// public TownDao townDao() {
// return new TownDao();
// }
@Autowired
@Bean
@Transactional
public SessionFactory sessionFactory(EntityManager entityManager) {
Session session = entityManager.unwrap(Session.class);
return session.getSessionFactory();
}
@Profile({"devel", "test"})
@Bean(initMethod = "doProvision")
public Provisioner provisioner() {
return new Provisioner();
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Main.class);
ApplicationContext ctx = app.run(args);
// CountryDao countryDao = ctx.getBean(CountryDao.class);
// List<Country> countries = countryDao.getCountries();
// UsersDao usersDao = ctx.getBean(UsersDao.class);
//
// List<User> users = usersDao.getAllUsers();
// System.out.println(users);
}
}
此代码在使用 Spring Boot 1.5.11.RELEASE 时有效。但不适用于 Spring Boot 2.0.0.RELEASE。
当我运行代码时,由于循环依赖,没有创建 ApplicationContext。
控制台有输出。
19:44:31.282 [main] WARN o.s.c.a.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sessionFactory' defined in cz.moravec.Main: Unsatisfied dependency expressed through method 'sessionFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.orm.jpa.SharedEntityManagerCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sessionFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?
Disconnected from the target VM, address: '127.0.0.1:11537', transport: 'socket'
19:44:31.286 [main] INFO o.s.b.a.l.ConditionEvaluationReportLoggingListener -
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
19:44:31.288 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| sessionFactory defined in cz.moravec.Main
↑ ↓
| org.springframework.orm.jpa.SharedEntityManagerCreator#0
└─────┘
Maven pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>cz.moravec</groupId>
<artifactId>semester_project</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
【问题讨论】:
-
为什么是
@Transactional这个方法?你到底为什么要得到EntityManager得到Session得到SessioNFactory。如果有一种复杂的方法可以获取SessionFactory,那就是它,我真的很惊讶它甚至可以工作。而是注入EntityManagerFactory并将其解包到SessionFactory。 -
没有@Transactional 我得到Hibernate 无法解开接口org.hibernate.SessionFactory,
-
好吧,这行得通,我以前确实有过这样的情况,但我正在尝试修复它。但这并不能解决我的循环依赖问题......应用程序上下文中一些bean的依赖关系形成了一个循环:┌─────┐ | cz.moravec.Main 中定义的 sessionFactory └──────┘
-
@JanMoravec 你找到答案了吗?我现在面临同样的问题。
-
对不起,我没有解决问题。
标签: java hibernate spring-boot jpa inject