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

Hibernate 4升级至5后出现UnsupportedLockAttemptException锁模式不支持问题求助

解决Hibernate 5升级后的UnsupportedLockAttemptException问题

这个问题我在从Hibernate 4升级到5的时候也碰到过,核心原因是同一事务内对同一ID的实体既做了读取又做了写入操作,加上Hibernate 5对Session缓存和不可变实体的处理逻辑更严格,导致了锁模式不支持的异常。咱们一步步来解决:

首先定位问题根源

从错误栈可以看到,异常来自ImmutableEntityEntry.setLockMode,说明你的MailHistory实体要么被标记了@Immutable注解,要么Hibernate将其识别为不可变实体。当你在同一Session(事务)中:

  1. 先通过getMailHistoryByReqId加载了某个reqId的MailHistory实例到Session缓存
  2. 之后又尝试创建同一个reqId的新MailHistory并持久化
  3. DAO的persist方法里可能调用了session.refresh(),触发了对缓存中已有实体的锁操作,但不可变实体不允许这种操作,于是抛出异常

具体解决方案

1. 检查并调整实体类的@Immutable注解

如果你的MailHistory实体类加了@Immutable:

  • 如果业务上允许该实体被修改或重新持久化,直接移除@Immutable注解即可,这是最直接的解决方式
  • 如果业务必须保持实体不可变,那就要调整操作逻辑,避免同一事务内对同一ID的实体既读又写

2. 清理Session缓存,避免实体冲突

在读取完MailHistory后,立即将其从Session缓存中移除,这样后续创建新实体时就不会有缓存冲突。修改你的getMailHistoryByReqId方法:

public MailHistory getMailHistoryByReqId(String reqId) {
    MailHistory mh = session.get(MailHistory.class, reqId);
    if (mh != null) {
        session.evict(mh); // 将已加载的实体从Session缓存中清除
    }
    return mh;
}

这样后续执行createNewMailHistory时,Session里没有旧的实体实例,就不会触发冲突的锁操作。

3. 拆分事务,隔离读写操作

把循环内的读写逻辑放到一个新的事务中,每次处理一个reviewer时都使用独立的Session,避免跨操作的缓存干扰。调整定时任务代码:

@Transactional(readOnly = false)
@Scheduled(cron = "${mail.cron.reviewer.task.reminder}")
public void sendPendingReviewerTaskRemainderEmail() {
    // 初始化pendingTasks等逻辑...
    for(Reviewers reviewer: pendingTasks) {
        // 每个reviewer的处理都用新事务
        handleSingleReviewerTask(reviewer);
    }
}

// 用REQUIRES_NEW传播级别,每次调用都会开启新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void handleSingleReviewerTask(Reviewers reviewer) {
    MailHistory mh = mailHistoryDAO.getMailHistoryByReqId(reviewer.getReqId());
    // 业务判断逻辑...
    if (someCondition) {
        mailHistoryDAO.createNewMailHistory(reviewer.getReqId(), params);
    }
}

4. 检查DAO的persist方法,移除不必要的refresh调用

查看MailHistoryDAO.persist方法的代码,如果里面有调用session.refresh(mailHistory),可以尝试移除这个调用——因为在插入新实体时,refresh操作是不必要的,反而会触发对Session缓存的检查,导致冲突。

内容的提问来源于stack exchange,提问作者gene b.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:27:43