You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC多线程场景下保存Hibernate实体出现LazyInitializationException问题

问题根因
  • Spring 默认将Hibernate Session(JPA EntityManager)的生命周期与请求线程绑定,主线程的请求处理完成后Session就会被关闭
  • jpaRepository.getOne() 返回的是懒加载代理对象,不会立即执行数据库查询,只有访问属性时才触发查询,子线程没有存活的Session,因此抛出LazyInitializationException
  • 你自行创建的子线程不受Spring事务管理器管理,就算createEntity方法加了@Transactional注解也不会生效,无法自动为子线程创建新的Session
可行解决方案

方案1:替换getOne为findById(改动最小,优先推荐)

findById会立即执行SQL查询返回真实实体,不会生成懒加载代理,完全避开Session依赖问题,只需修改createEntity方法的查询逻辑:

// 替换原有的entitySaved = jpaRepository.getOne((Long) entity.getId());
entitySaved = jpaRepository.findById((Long) entity.getId())
        .orElseThrow(() -> new EntityNotFoundException("实体不存在,ID:" + entity.getId()));

方案2:使用Spring异步管理替代自定义子线程

不要手动创建子线程,改用Spring自带的异步任务管理,Spring会自动为异步线程绑定独立的Session,事务注解也能正常生效:

  1. 项目启动类添加@EnableAsync注解开启异步功能
  2. 将通知标记已读的逻辑封装到单独的Bean方法中,方法添加@Async和@Transactional注解
  3. 控制器中直接调用该异步方法即可,无需自行维护线程池

该方案符合Spring开发规范,还能避免自行管理线程可能带来的资源泄露、并发数失控问题。

方案3:手动为子线程绑定Session

如果必须保留自定义子线程的实现,可以在子线程执行数据库操作前手动绑定EntityManager:

// 先注入EntityManagerFactory
@Autowired
private EntityManagerFactory entityManagerFactory;

// 子线程run方法内处理逻辑
public void run() {
    EntityManager em = entityManagerFactory.createEntityManager();
    try {
        EntityManagerHolder emHolder = new EntityManagerHolder(em);
        TransactionSynchronizationManager.bindResource(entityManagerFactory, emHolder);
        // 此处执行你的数据库操作,比如调用createEntity方法
    } finally {
        EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(entityManagerFactory);
        EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
    }
}

该方案代码侵入性较高,需要手动管理资源,不优先推荐。

额外优化建议

你现在的实现是把ES查询到的全量Notification实体传到子线程,实际仅需要传输通知ID列表即可,还可以进一步优化为批量更新,不用循环单条查询修改:

// 直接写JPQL批量更新,一次操作完成所有通知的已读标记
@Modifying
@Query("update Notification n set n.opened = true where n.id in :idList")
void batchMarkOpened(List<Long> idList);

该方案省略了查询、merge的步骤,性能更高,也完全避开了懒加载相关的问题。


内容的提问来源于stack exchange,提问作者user7332139

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:24:04