org.hibernate.UnsupportedLockAttemptException:不支持锁定模式:Hibernate 4->5 升级

org.hibernate.UnsupportedLockAttemptException: Lock mode not supported : Hibernate 4->5 Upgrade

我们刚刚在我们的应用程序中升级了 Hibernate 4->5。以下代码用于在 Hibernate 4 中工作。有一个作业从 MAIL_HISTORY_T 获取一些数据,并且可以选择写入 MAIL_HISTORY_T 以及在同一事务中。

@Transactional(readOnly = false)
@Scheduled(cron = "${mail.cron.reviewer.task.reminder}") 
public void sendPendingReviewerTaskRemainderEmail() {
    //...
    for(Reviewers reviewer: pendingTasks) {
        // Read from MAIL_HISTORY_T
        MailHistory mh = mailHistoryDAO.getMailHistoryByReqId(reviewer.getReqId()); 
        //...
        if (someCondition) {
            // Write to MAIL_HISTORY_T
            mailHistoryDAO.createNewMailHistory(reviewer.getReqId(), params); 
        }
    }
}

错误:

org.hibernate.UnsupportedLockAttemptException: Lock mode not supported
    at org.hibernate.engine.internal.ImmutableEntityEntry.setLockMode(ImmutableEntityEntry.java:128) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:220) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:52) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1295) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1247) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
    at app.mcs.dao.MailHistoryDAO.persist(MailHistoryDAO.java:40) ~[classes/:]

MAIL_HISTORY_T 上的读取和写入操作引用相同的请求 ID。

有什么想法吗?

您的代码以某种方式创建了 ImmutableEntityEntry,这是 Hibernate 5 中的新介绍。

根据ImmutableEntityEntry代码,它只支持LockMode.NONELockMode.READ(参见ImmutableEntityEntry#setLockMode方法)。

您的代码正在读取和更新同一个实体,因此休眠很可能将 LockMode 设置为 LockMode.PESSIMISTIC_WRITEImmutableEntityEntry 不支持。

能否请您检查一下您在 Hibernate 5 更新之前收到的是哪个 AbstractEntityEntry 实例。

编辑 :- 休眠中已经存在一个关于此 https://hibernate.atlassian.net/browse/HHH-13601 的错误。

目前,我不确定您如何获得 MutableEntityEntry 以帮助您更改实体。

我们通过将 写入操作重写为本机 SQL 来修复此问题。 Read操作不变。

所以之前的Hibernate-basedcreateNewMailHistory()现在是NativeSQL:

    sessionFactory.getCurrentSession().createNativeQuery("insert "
            + "    into "
            + "        MAIL_HISTORY_T "
            + "        (ID, MAIL_TEMPLATE_ID, MAIL_IDENTIFIER, REQUEST_ID, SYSTEM_COMMENTS, CREATED_DATE, CREATED_BY) "
            + "    values "
            + "        (nextval('mh_seq'), :mailTemplateId, :mailIdentifier, :requestId, :systemComments, :createdDate, :createdBy)")
        .setParameter("mailTemplateId", mailTemplateDAO.findByShortIdentifier(mailIdentifier).getId())
        .setParameter("mailIdentifier", mailIdentifier)
        .setParameter("requestId", req.getId())
        .setParameter("systemComments", systemComments)
        .setParameter("createdDate", new Date())
        .setParameter("createdBy", null)
        .executeUpdate();
}