Spring Boot 2.0/Hibernate 5中获取SessionFactory遇EntityManagerFactory注入空指针问题
我来帮你搞定这个问题!在Spring Boot 2.x及后续版本中,HibernateJpaSessionFactoryBean确实已经被废弃,官方推荐通过EntityManagerFactory的unwrap方法来获取SessionFactory。你遇到的注入null、循环依赖问题,大多是配置方式不当导致的,下面是具体的解决方案:
1. 确认依赖配置正确
首先要保证你的项目中引入了Spring Data JPA的核心依赖,Spring Boot会基于这个依赖自动配置EntityManagerFactory Bean。
如果是Maven项目,在pom.xml中添加:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
如果是Gradle项目,在build.gradle中添加:
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2. 正确配置SessionFactory的Bean
不要手动实例化EntityManagerFactory,而是让Spring自动注入它。这里要注意避免循环依赖,正确的做法是通过@Bean方法接收Spring自动配置好的EntityManagerFactory,再从中解包出SessionFactory:
import org.hibernate.SessionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.persistence.EntityManagerFactory; @Configuration public class HibernateConfig { // 直接注入Spring自动配置的EntityManagerFactory @Bean public SessionFactory sessionFactory(EntityManagerFactory entityManagerFactory) { return entityManagerFactory.unwrap(SessionFactory.class); } // 可选:如果需要事务管理器,也基于EntityManagerFactory配置 @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
3. 检查application.properties的JPA配置
确保数据库连接和JPA/Hibernate的配置没有错误,否则Spring无法正确初始化EntityManagerFactory:
# 数据库连接 spring.datasource.url=jdbc:mysql://localhost:3306/your_database spring.datasource.username=your_username spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # JPA/Hibernate配置 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
4. 解决循环依赖问题
如果出现循环依赖异常,通常是因为自定义Bean和EntityManagerFactory/SessionFactory之间形成了依赖闭环。可以尝试以下方案:
- 用构造注入替代字段注入(推荐,Spring更易处理构造注入的依赖关系)
- 在依赖的Bean上添加
@Lazy注解,延迟加载该Bean,打破循环链 - 重构代码,避免在配置类或初始化逻辑中过早依赖
SessionFactory,把业务逻辑放到Service层
5. 在业务类中使用SessionFactory
配置完成后,就可以在Service或其他Spring管理的Bean中直接注入SessionFactory使用了:
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.stereotype.Service; import javax.transaction.Transactional; @Service public class YourBusinessService { private final SessionFactory sessionFactory; // 构造注入(推荐) public YourBusinessService(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional public void executeHibernateOperation() { Session session = sessionFactory.getCurrentSession(); // 执行你的Hibernate操作,比如查询、更新等 } }
常见排查点
- 检查启动类是否添加了
@SpringBootApplication注解,且扫描范围覆盖了配置类和JPA实体类所在的包 - 如果有自定义的
EntityManagerFactory配置,检查是否覆盖了Spring Boot的自动配置,导致Bean无法正常生成 - 查看启动日志,寻找
EntityManagerFactory初始化失败的错误信息(比如数据库连接失败、实体类映射错误等)
内容的提问来源于stack exchange,提问作者Stealth Rabbi
相关产品推荐
相关产品推荐

