1 Reply Latest reply on Jul 11, 2008 6:25 AM by admin.admin.email.tld

    Problem with versionning and passivating entities

    bonaparte

      I 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:



      1. i look for a list of employees (open conversation 1)

      2. on the list i can click and go to see a detail of an employee (open conversation 2 and version 1)

      3. on the detail page, i can click to update the employe (open conversation 3)

      4. after success updating, the application goes directly to detail page (close conversation 3)

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