Spring Boot 3+Hibernate 6如何复用已创建的Session/EntityManager实例?
解决方案:复用Spring Boot管理的Hibernate持久化实例
异常原因分析
抛出java.lang.IllegalArgumentException: Unable to locate persister: org.hibernate.collection.spi.PersistentBag,本质是Hibernate错误地将内部集合类型PersistentBag当作实体来处理。结合你的场景,问题并非实体扫描配置失效,而是直接操作Session时的上下文关联问题,或者误将集合对象传入了merge方法。
正确复用Spring已创建实例的方法
1. 直接使用Spring注入的EntityManager(推荐)
Spring管理的EntityManager已经关联了正确的持久化上下文,无需unwrap成Session,直接调用其API即可:
@PersistenceContext private EntityManager entityManager; @Transactional public <T> T merge(T object) { // 直接使用EntityManager的merge方法,复用Spring配置 return entityManager.merge(object); }
2. 注入Spring管理的SessionFactory获取Session
如果业务必须使用Hibernate的Session API,直接注入Spring维护的SessionFactory,通过getCurrentSession()获取当前事务上下文绑定的Session,确保复用已有的配置:
@Autowired private SessionFactory sessionFactory; @Transactional public <T> T merge(T object) { Session session = sessionFactory.getCurrentSession(); return session.merge(object); }
关键注意事项
- 确认传入
merge方法的是实体对象,而非Hibernate内部集合类型(如PersistentBag)。如果误将实体的集合属性(如entity.getOrders())传入merge,会触发该异常。 - 确保
@Transactional注解生效,Spring会自动将Session/EntityManager绑定到当前事务上下文,避免出现脱离配置的实例。
内容的提问来源于stack exchange,提问作者JayDesAt
相关产品推荐
相关产品推荐

