Reputation: 11974
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?
Upvotes: 0
Views: 540
Reputation: 11974
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();
}
Upvotes: 1
Reputation: 4604
Somehow your code is creating ImmutableEntityEntry which is new introduction in Hibernate 5.
As per ImmutableEntityEntry
code, it only support LockMode.NONE
& LockMode.READ
(see ImmutableEntityEntry#setLockMode
method).
Your code is reading & updating same entity so it is most likely hibernate is setting LockMode as LockMode.PESSIMISTIC_WRITE
which is not supported by ImmutableEntityEntry
.
Can you please check which AbstractEntityEntry
instance you were receiving prior to Hibernate 5 update.
Edit :- There already exists a bug in hibernate regarding this https://hibernate.atlassian.net/browse/HHH-13601.
Currently,I am not sure how you can obtain MutableEntityEntry
in your case which will help you to change your entity.
Upvotes: 1