Announcement Announcement Module
Collapse
No announcement yet.
Can't seem to catch a StaleObjectStateException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't seem to catch a StaleObjectStateException

    Just wondering why I'm not able to catch this Exception?

    Just using a pretty standard extended HibernateDaoSupport with a delete method:

    Code:
    public class RecipeListDAO extends HibernateDaoSupport {
    	
    	public RecipeListDAO() {
    		super();
    	}
    
    	public void deleteRecipeItem( RecipeList recipe ) {
                 try {
    		getHibernateTemplate().delete(recipe);
                 }
                  catch( StaleObjectStateException ex ) {
                      ex.printStackTrace();
                 }
            }
    }
    This bit of code is buried in my Web Application and when I have two browsers open and one happens to delete a RecipeList item that has already been deleted by the second browser window a StaleObjectStateException gets thrown.

    I'm at my witts end and a Spring noob.

    I'm not doing any TransactionProxy AOP stuff in my applicationContext.xml file.

    Would you normally expect to be able to catch the StaleObjectStateException at this point using the HibernateTemplate? Or am I seriously missing a concept?

    I attempted to go down a level and get a Hibernate Session using getSession() and manually doing the session.delete(recipe) and session.flush commands myself thinking that at a lower level I'd be able to catch the exception... But no luck.

    Any Ideas or hints would be most helpful.

    Thank you[/code]

  • #2
    The StatleObjectStateException is a Hibernate checked exception. Spring catches all HibernateExceptions and wraps them in an unchecked Spring DataAccessException (or subclass of). You should grab this exception and look for the inner cause.

    See the JavaDoc for more details on DataAccessException

    Rob

    Comment


    • #3
      So, given your recommendation, I should do something like this:

      Code:
      public class RecipeListDAO extends HibernateDaoSupport {
         
         public RecipeListDAO() {
            super();
         }
      
         public void deleteRecipeItem( RecipeList recipe ) {
                   try {
                        getHibernateTemplate().delete(recipe);
                   }
                    catch( DataAccessException ex ) {
                        ex.printStackTrace();
                        if( ex.getCause() instanceof StaleObjectStateException ) {
                                  System.out.println("WH00T!  I triggered!!");
                       }
                        
                        //do some interesting recover logic
      
                   }
              }
      }
      If this is indeed the correct Syntax I am still not able to catch the DataAccessException or the StaleObjectStateException..

      Heh... Or it could be an error that's completely unrelated to my code. I'm assuming that you can catch RuntimeExceptions the same way you catch java.lang.Exceptions, yes?

      Thanks all again for your help!


      Error listing and applicationContext.xml
      Code:
      2004-10-29 13:32:08,784 WARN StaleObjectStateException - An operation failed due to stale data
      net.sf.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) for zorolrecipemgmt.hibernate.RecipeList instance with identifier: 80
      	at net.sf.hibernate.persister.AbstractEntityPersister.check(AbstractEntityPersister.java:506)
      	at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:596)
      	at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
      	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2418)
      	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2376)
      	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240)
      	at org.springframework.orm.hibernate.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:214)
      	at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:201)
      	at org.springframework.orm.hibernate.HibernateTemplate.delete(HibernateTemplate.java:381)
      	at recipemgmt.hibernate.dao.RecipeListDAO.deleteRecipeItem(RecipeListDAO.java:58)
      	at recipemgmt.app.RecipeMgmtScreen.deleteRecipeListItem(RecipeMgmtScreen.java:398)
      	at recipemgmt.app.RecipeMgmtScreen.actionPerformed(RecipeMgmtScreen.java:189)
      	at nextapp.echo.AbstractButton.fireActionPerformed(AbstractButton.java:268)
      	at nextapp.echo.AbstractButton$EventForwarder.actionPerformed(AbstractButton.java:127)
      	at nextapp.echo.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:88)
      	at nextapp.echo.DefaultButtonModel.doAction(DefaultButtonModel.java:77)
      	at nextapp.echo.AbstractButton.doAction(AbstractButton.java:238)
      	at nextapp.echoservlet.ui.AbstractButtonUI.clientAction(AbstractButtonUI.java:76)
      	at echopoint.ui.PushButtonUI.clientAction(PushButtonUI.java:85)
      	at nextapp.echoservlet.ControllerInputProcessor.doAction(ControllerInputProcessor.java:144)
      	at nextapp.echoservlet.ControllerInputProcessor.<init>&#40;ControllerInputProcessor.java&#58;113&#41;
      	at nextapp.echoservlet.ControllerInputProcessor.process&#40;ControllerInputProcessor.java&#58;44&#41;
      	at nextapp.echoservlet.Controller.service&#40;Controller.java&#58;604&#41;
      	at nextapp.echoservlet.Connection.process&#40;Connection.java&#58;441&#41;
      	at nextapp.echoservlet.EchoServer.process&#40;EchoServer.java&#58;303&#41;
      	at nextapp.echoservlet.EchoServer.doPost&#40;EchoServer.java&#58;223&#41;
      	at javax.servlet.http.HttpServlet.service&#40;HttpServlet.java&#58;717&#41;
      	at javax.servlet.http.HttpServlet.service&#40;HttpServlet.java&#58;810&#41;
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter&#40;ApplicationFilterChain.java&#58;237&#41;
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter&#40;ApplicationFilterChain.java&#58;157&#41;
      	at org.apache.catalina.core.StandardWrapperValve.invoke&#40;StandardWrapperValve.java&#58;214&#41;
      	at org.apache.catalina.core.StandardValveContext.invokeNext&#40;StandardValveContext.java&#58;104&#41;
      	at org.apache.catalina.core.StandardPipeline.invoke&#40;StandardPipeline.java&#58;520&#41;
      	at org.apache.catalina.core.StandardContextValve.invokeInternal&#40;StandardContextValve.java&#58;198&#41;
      	at org.apache.catalina.core.StandardContextValve.invoke&#40;StandardContextValve.java&#58;152&#41;
      	at org.apache.catalina.core.StandardValveContext.invokeNext&#40;StandardValveContext.java&#58;104&#41;
      	at org.apache.catalina.core.StandardPipeline.invoke&#40;StandardPipeline.java&#58;520&#41;
      	at org.apache.catalina.core.StandardHostValve.invoke&#40;StandardHostValve.java&#58;137&#41;
      	at org.apache.catalina.core.StandardValveContext.invokeNext&#40;StandardValveContext.java&#58;104&#41;
      	at org.apache.catalina.valves.ErrorReportValve.invoke&#40;ErrorReportValve.java&#58;117&#41;
      	at org.apache.catalina.core.StandardValveContext.invokeNext&#40;StandardValveContext.java&#58;102&#41;
      	at org.apache.catalina.core.StandardPipeline.invoke&#40;StandardPipeline.java&#58;520&#41;
      	at org.apache.catalina.core.StandardEngineValve.invoke&#40;StandardEngineValve.java&#58;109&#41;
      	at org.apache.catalina.core.StandardValveContext.invokeNext&#40;StandardValveContext.java&#58;104&#41;
      	at org.apache.catalina.core.StandardPipeline.invoke&#40;StandardPipeline.java&#58;520&#41;
      	at org.apache.catalina.core.ContainerBase.invoke&#40;ContainerBase.java&#58;929&#41;
      	at org.apache.coyote.tomcat5.CoyoteAdapter.service&#40;CoyoteAdapter.java&#58;160&#41;
      	at org.apache.coyote.http11.Http11Processor.process&#40;Http11Processor.java&#58;793&#41;
      	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection&#40;Http11Protocol.java&#58;702&#41;
      	at org.apache.tomcat.util.net.TcpWorkerThread.runIt&#40;PoolTcpEndpoint.java&#58;571&#41;
      	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run&#40;ThreadPool.java&#58;644&#41;
      	at java.lang.Thread.run&#40;Thread.java&#58;536&#41;
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
      
      <beans>
      
      	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
      		<property name="driverClassName"><value>org.postgresql.Driver</value></property>
      		<property name="url"><value>jdbc&#58;postgresql&#58;//localhost/recipe</value></property>
      		<property name="username"><value></value></property>
      		<property name="password"><value></value></property>
      	</bean>
      	
      	
      	<bean id="tomcatSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      		<property name="driverClassName"><value>org.postgresql.Driver</value></property>
      		<property name="url"><value>jdbc&#58;postgresql&#58;//localhost/tomcatusers</value></property>
      		<property name="username"><value></value></property>
      		<property name="password"><value></value></property>
      	</bean>
      
      
      	<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
      		<property name="dataSource"><ref local="dataSource"/></property>
      		<property name="mappingResources">
      			<list>
      				<value>zorolrecipemgmt/hibernate/RecipeList.hbm</value>
      
      			</list>
      		</property>
      		<property name="hibernateProperties">
      			<props>
      			    <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
      				<prop key="hibernate.dialect">net.sf.hibernate.dialect.PostgreSQLDialect</prop>
      				<prop key="hibernate.show_sql">true</prop>
      				
      			</props>
      		</property>
      	</bean>
      
      
      	<bean id="recipeListDAO" class="recipemgmt.hibernate.dao.RecipeListDAO">
      		<property name="sessionFactory"><ref local="sessionFactory"/></property>
      	</bean>
      
      
      	<bean id="recipeListFactory" class="zorolrecipemgmt.beans.RecipeListFactory">
      		<property name="recipeListDAO">
      			<ref bean="recipeListDAO"/>
      		</property>
      	</bean>
      
      	
      </beans>

      Comment


      • #4
        Found the problem...

        It appears that my code has properly caught the StaleObjectStateException after all.

        The problem was that I had Tomcat configured to run in debug mode under Eclipse.

        When Tomcat encountered the StaleObjectStateException, it Suspended the current thread. I assumed that this meant that there was a problem with my code not properly catching the exception... I simply resumed through the exception and all is well.

        FYI: you can also configure Eclipse to behave in a certain way when an Exception occurs. In this case, I will be configuring Eclipse to not suspend when it sees a StaleObjectStateException. Very cool.

        a big homer simpson "Doh!"

        Comment

        Working...
        X