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) );
}
}
}