Spring Boot 2.0.0中EntityManager与SessionFactory循环依赖问题求助
解决Spring Boot 2.0.0中SessionFactory Bean的循环依赖问题
嘿,我完全懂你遇到的这个头疼问题——在Spring Boot 2.0.0里手动创建SessionFactory Bean时,注入EntityManager触发了循环依赖,这其实是Spring JPA自动配置和Hibernate底层关联逻辑导致的闭环。下面给你拆解原因和可行的解决办法:
为什么会出现循环依赖?
在Spring Boot整合Hibernate的场景下,EntityManagerFactory的底层实现是HibernateEntityManagerFactory,它本身就依赖SessionFactory。而当你尝试注入EntityManager来获取SessionFactory时,EntityManager又依赖EntityManagerFactory,这就形成了死循环:EntityManagerFactory → SessionFactory → EntityManager → EntityManagerFactory
两种实用的解决方案
方案1:直接从EntityManagerFactory获取SessionFactory(推荐)
这种方式绕过了直接注入EntityManager,直接利用Spring已经初始化好的EntityManagerFactory来提取SessionFactory,从根源上避免循环依赖:
package cz.moravec; import org.hibernate.SessionFactory; import org.hibernate.jpa.HibernateEntityManagerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import javax.persistence.EntityManagerFactory; @SpringBootApplication @EntityScan(basePackages = "cz.moravec.provisioning") public class YourApplication { @Bean public SessionFactory sessionFactory(EntityManagerFactory entityManagerFactory) { // 校验并转换为Hibernate的EntityManagerFactory实现 if (entityManagerFactory instanceof HibernateEntityManagerFactory) { return ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory(); } throw new IllegalArgumentException("当前EntityManagerFactory不是Hibernate的实现类"); } public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
方案2:用@Lazy延迟注入打破循环
如果你确实需要通过EntityManager来获取SessionFactory,可以给EntityManager的注入加上@Lazy注解,让Spring延迟初始化这个依赖,从而打破循环链:
@Bean public SessionFactory sessionFactory(@Lazy javax.persistence.EntityManager entityManager) { return entityManager.unwrap(org.hibernate.Session.class).getSessionFactory(); }
额外小提示
- 优先选方案1,它更贴合Spring Boot的自动配置逻辑,能减少后续版本升级的兼容性问题。
- 如果只是需要使用Hibernate的Session,其实可以直接注入
EntityManager后unwrap成Session,不一定非要单独创建SessionFactoryBean。
内容的提问来源于stack exchange,提问作者Jan Moravec
相关产品推荐
相关产品推荐

