Problem with versionning and passivating entities
bonaparte Jul 9, 2008 5:57 PMI use Seam 2.0.2.SP1 and i faced a problem with version checking between entities instance and passivated attribute.
The model of my application is very simple:
- i look for a list of employees (open conversation 1)
- on the list i can click and go to see a detail of an employee (open conversation 2 and version 1)
- on the detail page, i can click to update the employe (open conversation 3)
- after success updating, the application goes directly to detail page (close conversation 3)
- on the detail page, i click on a button to go back to the updated list (close conversation 2)
The problem lies on step 4, because i stop the conversation 3 before going back to conversation 2 and so THERE'S NO PASSIVATION OF MY ENTITY and so the version number is not updated.
Consequence: on the after render response of step 5, there's a control of instance version number against passivated version number and it throw the following exception:
[09/07/08 17:53:14:343 CEST] 0000002d SystemOut O ERROR [SeamPhaseListener ] user= - uncaught exception org.hibernate.StaleStateException: current database version number does not match passivated version number at org.jboss.seam.persistence.HibernatePersistenceProvider.checkVersion(HibernatePersistenceProvider.java:281) at org.jboss.seam.persistence.HibernatePersistenceProvider.checkVersion(HibernatePersistenceProvider.java:190) at org.jboss.seam.contexts.PassivatedEntity.checkVersion(PassivatedEntity.java:133) at org.jboss.seam.contexts.PassivatedEntity.getEntityFromEntityManager(PassivatedEntity.java:118) at org.jboss.seam.contexts.PassivatedEntity.toEntityReference(PassivatedEntity.java:73) at org.jboss.seam.contexts.EntityBean.activate(EntityBean.java:67) at org.jboss.seam.contexts.ServerConversationContext.unflush(ServerConversationContext.java:258) #
To make the code run, i need to suppress the long running check in the ServerConversationContext class so that even in the case of a no long running conversation (step 4), i can passivate the version number of my updated item.
Block of code:
public void flush() { boolean longRunning = !isCurrent() || Manager.instance().isLongRunningConversation(); // need to escape this control to make the code run even for closing conversations... //if ( longRunning ) if (true) { //force update for dirty mutable objects for (String key: getNamesForAllConversationsFromSession()) { Object attribute = session.get(key); if ( attribute!=null && isAttributeDirty(attribute) ) { session.put(key, attribute); } } //remove removed objects for (String name: removals) { session.remove(getKey(name)); } removals.clear(); //add new objects for (Map.Entry<String, Object> entry: additions.entrySet()) { session.put( getKey( entry.getKey() ), entry.getValue() ); } additions.clear(); } else { //TODO: for a pure temporary conversation, this is unnecessary, optimize it for ( String name: getNamesFromSession() ) { session.remove( getKey(name) ); } } }