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: