Issue
We've just upgraded Hibernate 4->5 in our application. The following code used to work in Hibernate 4. There is a job which fetches some data from MAIL_HISTORY_T
and can optionally write into MAIL_HISTORY_T
as well in the same transaction.
@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);
}
}
}
Error:
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/:]
Both the Read and Write operations on MAIL_HISTORY_T
reference the same Request ID.
Any thoughts?
Solution
We fixed this by rewriting the Write operation as Native SQL. The Read operation remains unchanged as before.
Therefore, the previous Hibernate-based createNewMailHistory()
is now 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();
}
Answered By - gene b.
Answer Checked By - Willingham (JavaFixing Volunteer)