1 Reply Latest reply on Jun 2, 2009 3:31 PM by Clinton Parham

    How to reload page on OptimisticLockException?

    Gregory Nikle Apprentice

      Hi,
      When other user transaction update entity, how can i reload page why I get
      OptimisticLockException



      so far user is redirected to main page:


      <exception class="javax.persistence.OptimisticLockException">
          <redirect view-id="/main.xhtml" />
      </exception>



      Can I reload/refresh page (form submit) on OptimisticLockException like that:


      <exception class="javax.persistence.OptimisticLockException">
          <redirect view-id="#{request.refresh}" />
      </exception>


        • 1. Re: How to reload page on OptimisticLockException?
          Clinton Parham Newbie
          I have the same challenge. Can someone point us in the right direction?

          This is my scenario: the user must complete a 3 page wizard. A conversation begins on page 1. On page 2 the user chooses from a dropdown list of available appointments - only 1 person is allowed to choose any listed appointment. On reaching page 3, the conversation ends.

          It's very likely that multiple users will reach page 2 and try choosing the same appointment. When multiple users choose the same appointment and submit page 2, my seam component executes entityManager.flush() which throws the StaleObjectStateException  for the unlucky user who comes in last. I need page 2 to reload for the unlucky user so they can choose a different appointment. But how?

          Here's the action code that executes when the user tries to submit page 2:

          `public String incrementTimeslot() {
            if (chosenTimeslot == null) {
              return "";
            } else {
              chosenTimeslot.setCurrentenrollments((short) (chosenTimeslot.getCurrentenrollments() + 1));
            }
            try {
              entityManager.flush();
            } catch (StaleObjectStateException e) {
              facesMessages.add("Someone else got your appointment!");
              entityManager.refresh(event);
              return null;
            }`

          This is a seam-gen (Seam 2.1.1GA) WAR project running on JBoss 4.2.3GA.

          Here's how I trigger the action:

          <h:commandButton id="dataEntry" value="Next" action="#{enrollWizard.incrementTimeslot}" />

          Here's the content of persistence-dev-war.xml:

          <persistence-unit name="myproject" transaction-type="JTA">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <jta-data-source>java:/myprojectDatasource</jta-data-source>
          <properties>
          <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
          <property name="hibernate.hbm2ddl.auto" value="update"/>
          <property name="hibernate.show_sql" value="true"/>
          <property name="hibernate.format_sql" value="true"/>
          <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
          </properties>
          </persistence-unit>

          Abbreviated stacktrace:

          08:44:01,941 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
          org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.mydomain.myproject.Timeslot#1]
               at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
               at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
               at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
               at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
               at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
               at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
               at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
               at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
               at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
               at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
               at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
               at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:296)
               at org.jboss.seam.persistence.EntityManagerProxy.flush(EntityManagerProxy.java:92)
               at com.mydomain.myproject.EnrollWizard.incrementTimeslot(EnrollWizard.java:88)
               at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
               at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
               at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
               at java.lang.reflect.Method.invoke(Unknown Source)

          Help greatly appreciated. Thank you!