NetBeans 8.2运行后端报Session/EntityManager is closed异常求助
报错根因与修复方案
根因说明
java.lang.IllegalStateException: Session/EntityManager is closed报错的本质是调用Hibernate数据库操作时,使用的Session对象已经被关闭。仅本地复现的原因和环境、任务触发时机差异直接相关:
- 本地Hibernate Session生命周期配置和其他同事不一致,Session自动回收时机更早。该方法由
TimerThread异步线程调用,外部传入的Session到实际执行数据库操作时已经被回收;其他同事的环境Session生命周期更长,可覆盖任务执行周期因此无报错。 - 本地时区触发了特殊的执行时机:该定时任务逻辑与时区挂钩,本地时区刚好会在项目启动阶段就触发任务执行,此时容器上下文还未完全初始化完成,Session已被提前关闭;其他同事的时区不会在项目启动阶段触发任务,运行时调用拿到的都是有效Session。
- 代码存在隐性缺陷:方法直接使用外部传入的Session,未做有效性校验。本地任务调度速度、数据库连接超时配置与其他同事不同,Session从传入到实际使用的间隔超过超时时间,调用时已经失效。
修复方案
临时验证方案
将本地操作系统时区修改为可正常运行项目的同事一致,重启NetBeans和项目后观察是否报错,若不再报错即可确认是时区触发任务时机的问题。
永久代码修复
- 异步定时任务不要复用外部传入的Session,每次执行任务时主动从
SessionFactory获取新的Session,自行管理事务生命周期,避免拿到失效Session:
// 替换原有外部传入Session的逻辑示例 Session session = sessionFactory.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); // 原有业务逻辑代码 tx.commit(); } catch (Exception e) { if (tx != null) tx.rollback(); e.printStackTrace(); } finally { if (session != null) session.close(); }
- 新增Session有效性校验,每次调用Session操作前先判断是否处于开启状态,不满足则重新获取:
if (session == null || !session.isOpen()) { session = sessionFactory.openSession(); }
- 给该定时任务增加启动延迟配置,等待容器上下文完全初始化完成后再开始执行,避免启动阶段获取到无效Session。
内容的提问来源于stack exchange,提问作者Jaehyuck Choi
相关产品推荐
相关产品推荐

