org.hibernate.不支持锁定尝试异常:不支持锁定模式:休眠 4->5 升级



我们刚刚在应用程序中升级了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的Read和Write操作引用同一个Request ID。

任何想法吗?

不知怎么的,你的代码正在创建ImmutableEntityEntry,这是Hibernate 5中新引入的。

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

你的代码正在读取&更新相同的实体,所以hibernate很可能将LockMode设置为LockMode.PESSIMISTIC_WRITE,而ImmutableEntityEntry不支持。

请检查在Hibernate 5更新之前收到的AbstractEntityEntry实例。

编辑:-在hibernate中已经存在一个关于这个https://hibernate.atlassian.net/browse/HHH-13601的bug。

目前,我不确定你如何在你的情况下获得MutableEntityEntry,这将有助于你改变你的实体。

我们通过将Write操作重写为Native SQL来解决这个问题。Read操作保持不变。

因此,以前基于hibernate的createNewMailHistory()现在是Native SQL:
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();
}

相关内容

  • 没有找到相关文章

最新更新