Re-Attaching Hibernate-Objects In New Transaction

Well i lovin it, using actionListener of JSF as the results of it is nothing less than the object itself, stored as a parameter of a UICommandButton or UICommandLink. The other thing is using direct mapping of values to input-elements.

For instance, following line gives me the whole object back:


 
	value=”#{WorkflowManager.taskInstances}”
	rows=”15″ columnClasses=”tableCol”>
	
                
		    
		
	        
	
      ….

Well if i want to save this current change of the name (do you see the inputText in the code, äh?), normaly you write following lines of code to achieve this:

...
Object ret = getHibernateTemplate().get(WorkflowPersistenceTemplate.class, persistenceTemplate.getId());
if (ret == null)
    id = (Long) getHibernateTemplate().save(persistenceTemplate);
else {
    id = persistenceTemplate.getId();
    getHibernateTemplate().update(merge);
}
  ...

So, the persistenceTemplate is the same object we have seen in the first code-snippet. I dont want to rebuild all of that peace of informations each time of HttpRequest to made up a new object - whats the time hu? In place of sucessfuly saving of the workflowtemplate we get punished with following exception:

Caused by: org.hibernate.NonUniqueObjectException: a different object with the s
ame identifier value was already associated with the session: [com.logicaldoc.wo
rkflow.persistence.WorkflowPersistenceTemplate#2]
        at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(State
fulPersistenceContext.java:590)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdat
e(DefaultSaveOrUpdateEventListener.java:284)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDeta
ched(DefaultSaveOrUpdateEventListener.java:223)
        at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdat
e(DefaultUpdateEventListener.java:33)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpda
te(DefaultSaveOrUpdateEventListener.java:70)
        at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564)
        at org.hibernate.impl.SessionImpl.update(SessionImpl.java:552)
        at org.hibernate.impl.SessionImpl.update(SessionImpl.java:544)
        at org.springframework.orm.hibernate3.HibernateTemplate$14.doInHibernate
(HibernateTemplate.java:715)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(Hibern
ateTemplate.java:419)
        ... 67 more

Why does hibernate bother us with this simple operation? Well if you receive this error, you have ran into the same problem as the rest of developers-world. If you load a object from the database into you application, Hibernate stores this in the Session-Cache. Hibernate supports transactions and in the most cases, one transaction is exact so lang as a request is done to the server. For instance, in my application i´ve got a transaction-intercepter added through spring, so a transaction-template will be used to commit/rollback a transaction after each request.

But you have another cache in your application being called your JSF-Brain. So, if you JSF-TreeComponent is in rebuild (a new HttpRequest is done), the already existing object in jsf will be used. Actually you work with an detached hibernate object!
If you storing this object into your database (see code-snippet two) you receive the already depicted errormessage.

So how can you “reattach” you object to the hibernate session? How can we put some candies to hibernate to make him happy? By simply using the merge-method of hibernate!

WorkflowPersistenceTemplate merge = (WorkflowPersistenceTemplate)getHibernateTemplate().merge(persistenceTemplate);

So, if you have done this, you have an attached object within the hibernate-session with you current values you´ve probably netered in the mean time! Merging does nothing more than obtaining the eventually available object in the session and applying the new values on it. You receive the “old” attached object with the new values.

Save it now before its gettin detached!! ;-D

Comments

Leave a Reply




Security Code: