Having a deadlock in webservice + hibernate… No idea why.
I have the following webservice code (core code of the function)
public String createImageRecipe(...)
{
Session session = ICDBHibernateUtil.getSessionFactory().getCurrentSession();
try
{
session.beginTransaction();
User user = (User) session.load(User.class, userid);
// Create the recipe
Recipe recipe = new Recipe();
...
...
...
session.save(recipe);
session.save(user);
...
...
...
session.update( recipe );
// Add new entry to activity log
Activitylog activityLog = new Activitylog( user,
(byte) ActivityTypeEnum.USER_SHARED_RECIPE.ordinal(),
new Date() );
activityLog.setRecipe(recipe);
TimelineProcessor.saveTimeline( activityLog, null, true );
session.getTransaction().commit();
endMeasurement();
return recipe.getRecipeid() + "," + recipe.getImageRecipeUrl();
}
catch (RuntimeException e)
{
ICDBHibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
throw e;
}
}
Now the timeline thread (TimelineProcessor) does the following (after getting the message):
Session session = ICDBHibernateUtil.getTimelineSessionFactory().openSession();
try {
session.getTransaction().begin();
...
...
...
TimelineId tlId = new TimelineId();
tlId.setUserId(userId);
User u = new User();
u.setUserid(userId);
Timeline tl = new Timeline(tlId, timelineData.getActivitylog(), u);
session.save(tl);
session.getTransaction().commit();
session.close();
} catch (Exception e) {
logger.error("Error while processing timeline :: ", e);
session.getTransaction().rollback();
}
}
Exceptions from log:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:435)
ERROR com.icdb.TimelineProcessor – processTimeline – Error while processing timeline ::
org.hibernate.exception.LockAcquisitionException: could not insert: [com.icdb.data.Activitylog]
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
ERROR com.icdb.TimelineProcessor – processTimeline – Error while processing timeline ::
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Will really appriciate help…
Thanks a lot
Well Hibernate is telling you what it doesn’t like:
You are opening two sessions, and have a transaction in each, and when you save the new timeline in the second session, it has an activityLog, and that activityLog has a user and a recipe that stem from the first session. That’s where Hibernate croaks.
I’m not sure i see what you are trying to accomplish. Is there a reason you need two separate sessions? Is the timeline something that’s semantically associated with the recipe/user entities or is it more like a timestamp collection? In the former case you probably want to store user, recipe and timeline in one and the same collection, or else you’ll end up with corrupt data if one transaction succeeds and the other one fails. In the latter case the Timestamp service should take value objects as arguments rather than entities, because you’re probably going to want to access it from different parts of your application.