-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: not getting StaleObjectStateException when I think I should
PostPosted: Thu Oct 21, 2004 11:44 pm 
Regular
Regular

Joined: Thu Sep 16, 2004 4:56 pm
Posts: 80
I wrote a simple JUnit test case which fails. Here is the summary
action: get NamedItem objects where id = 1 in two different sessions.
result: good. Sure enough, the instances are different like they are supposed to be.
action: I then change the second NamedItem's name property when in the detached state(ie. outside of a session).
action: I do the same with the first one.
action: I then commit the second one and the db correctly changes the version number up and you can see the update below
action: I commit the second one
result: bad? I think I was supposed to get a StaleObjectException but instead the Junit test fails when it calls the fail method meaning it ran the update and no exception at all occurred.

Anybody have any ideas?
thanks,
dean


Hibernate version:
2.1
Mapping documents:
<hibernate-mapping>
Code:
    <class
        name="biz.xsoftware.model.chap5.NamedItem"
        table="CHAP5_ITEM"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="id"
            column="ITEM_ID"
            type="java.lang.Long"
        >
            <generator class="increment">
            </generator>
        </id>

        <version
            name="version"
            type="int"
            column="version"
            access="property"
            unsaved-value="undefined"
        />

        <property
            name="name"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="name"
        />

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-NamedItem.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
The following is a JUnit test case that fails and I think should pass....
Code:
   public void testVersioning() throws Exception {
      SessionFactory sessionFactory = new Configuration()
                  .addClass(NamedItem.class)
                  .buildSessionFactory();
      NamedItem item1 = null;
      NamedItem item2 = null;
      
      //pretend first client gets NamedItem.id = 1
      Session session = sessionFactory.openSession();
      Transaction tx = session.beginTransaction();
      item1 = (NamedItem)session.load(NamedItem.class, new Long(1));      
      tx.commit();
      session.close();               

      //pretend second client gets NamedItem.id = 1 also
      session = sessionFactory.openSession();
      tx = session.beginTransaction();
      item2 = (NamedItem)session.load(NamedItem.class, new Long(1));      
      tx.commit();
      session.close();   
      
      assertTrue("item1 and item2 should not be the same object", item1 != item2);
      
      item2.setName("second client22");
      item1.setName("first client11");
      
      System.out.println("item1="+item1.getId());
      System.out.println("item2="+item2.getId());
      
      //2nd client makes modification and commits it
      session = sessionFactory.openSession();
      tx = session.beginTransaction();
      System.out.println("2. item2="+item2.getId());
      session.update(item2);
      tx.commit();
      session.close();            
      
      //expect 1st client to throw StaleObjectException
      session = sessionFactory.openSession();
      tx = session.beginTransaction();
      try {
         System.out.println("2. item1="+item1.getId());
         session.update(item1);
         fail("session.update should have thrown a StaleObjectException");
      } catch(StaleObjectStateException e) { /* gulp - test passes */ }
      tx.commit();
      session.close();      
   }

Full stack trace of any exception that occurs:
testVersioning(biz.xsoftware.chap5.BBTestVersioning)junit.framework.AssertionFailedError: session.update should have thrown a StaleObjectException
at biz.xsoftware.chap5.BBTestVersioning.testVersioning(BBTestVersioning.java:86)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at biz.xsoftware.chap5.BBTestVersioning.main(BBTestVersioning.java:40)

Name and version of the database you are using:
MySQL

The generated SQL (show_sql=true):
ibernate: select nameditem0_.ITEM_ID as ITEM_ID0_, nameditem0_.version as version0_, nameditem0_.name as name0_ from CHAP5_ITEM nameditem0_ where nameditem0_.ITEM_ID=?
Hibernate: select nameditem0_.ITEM_ID as ITEM_ID0_, nameditem0_.version as version0_, nameditem0_.name as name0_ from CHAP5_ITEM nameditem0_ where nameditem0_.ITEM_ID=?
item1=1
item2=1
2. item2=1
Hibernate: update CHAP5_ITEM set version=?, name=? where ITEM_ID=? and version=?
2. item1=1

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 21, 2004 11:54 pm 
Regular
Regular

Joined: Thu Sep 16, 2004 4:56 pm
Posts: 80
correction. Made a stupid mistake. My question now is why am I getting a HibernateException and not a StaleObjectStateException like the 'hibernate in action' book claims I should get.

Here is the exception I get when I try to commit the transaction....

Code:
testVersioning(biz.xsoftware.chap5.BBTestVersioning)net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
   at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:25)
   at net.sf.hibernate.persister.EntityPersister.update(EntityPersister.java:684)
   at net.sf.hibernate.persister.EntityPersister.update(EntityPersister.java:642)
   at net.sf.hibernate.impl.ScheduledUpdate.execute(ScheduledUpdate.java:52)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2418)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2372)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at biz.xsoftware.chap5.BBTestVersioning.testVersioning(BBTestVersioning.java:86)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at biz.xsoftware.chap5.BBTestVersioning.main(BBTestVersioning.java:40)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 22, 2004 1:15 am 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
hi,

you can search "NonBachtingBachter" in this forum. There're some other people (including myself) with the same 'problem' :)
The NonBatchingBatcher (if i'm right!) reacts a little bit different to the 'EntityPersister' ... in the same situtation 'update went wrong due to a concurrency situation' a HibernateException and not a StaleObjectException is thrown ...

My current workaround is to analyse the exception-message when i get a HibernateException during a 'saveOrUpdate'-Operation ... my opinion is, that's quite the same in this situation ...

perhaps someone 'official' could commit that or can write, why i'm wrong ... that would be perfect :)

gtx
curio


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.