Hi,
Perhaps I have missed something obvious but here is my issue...
I'm testing the concurrency handling of Hibernate3. I have code that I'm expecting to throw a concurrency exception but it is not.
The update sql generated updates no rows silently. I'd expect it to see that 0 rows where updated and throw an Exception?
I have tried a couple of things but they all silently are updating 0 rows :(
The general plan,
- fetch an Object
- Thread.sleep(20000);
// during the sleep time I update the DB using external tool (SQLPlus)
- update Object
- saveOrUpdate(), session.flush(), session.close();
I have logging on and the SQL and bind variables all look correct. The DB is as expected (the Hibernate update didn't succeed).
My problem is I'd expect a StaleObjectStateException to be thrown when 0 rows where updated??
Hibernate version: 3
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.auction">
<class name="Patient" table="HB_PATIENT" dynamic-update="true" optimistic-lock="version">
<id name="id">
<generator class="native">
<param name="sequence">hb_patient_s</param>
</generator>
</id>
<timestamp
column="lastupd"
name="lastupd"
access="field"
unsaved-value="undefined"
/>
<property name="firstName" column="first_name" />
<property name="lastName" column="last_name" />
<property name="dob"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Session s = factory.openSession();
try {
List list = s.createCriteria(Patient.class)
.add( Expression.eq("id", id) )
.list();
Patient p = (Patient) list.get(0);
System.out.println("Patient>> "+p);
System.out.println("sleeping...");
Thread.sleep(20000);
p.setFirstName(newName);
s.saveOrUpdate(p);
s.flush();
return p;
} catch (Exception e) {
e.printStackTrace();
//if (tx!=null) tx.rollback();
throw e;
} finally {
s.close();
}
Full stack trace of any exception that occurs:
na
Name and version of the database you are using:
Oracle9i
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
13:57:53,859 INFO SessionFactoryImpl:140 - building session factory
13:57:54,187 INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured
13:57:54,187 INFO SessionFactoryImpl:366 - Checking 0 named queries
conTest: 1
Hibernate: select this_.id as id0_, this_.lastupd as lastupd0_0_, this_.first_name as first3_0_0_, this_.last_name as last4_0_0_, this_.dob as dob0_0_ from HB_PATIENT this_ where this_.id=?
13:57:54,265 DEBUG IntegerType:59 - binding '1' to parameter: 1
13:57:54,312 DEBUG IntegerType:86 - returning '1' as column: id0_
13:57:54,328 DEBUG TimestampType:86 - returning '2005-04-20 13:31:20' as column: lastupd0_0_
13:57:54,328 DEBUG StringType:86 - returning 'yyy' as column: first3_0_0_
13:57:54,328 DEBUG StringType:86 - returning 'Bygrave' as column: last4_0_0_
13:57:54,328 DEBUG DateType:86 - returning '04 January 1980' as column: dob0_0_
Patient>> 1, yyy, Bygrave, 1980-01-04
sleeping...
Hibernate: update HB_PATIENT set lastupd=?, first_name=? where id=? and lastupd=?
13:58:14,359 DEBUG TimestampType:59 - binding '2005-04-20 13:58:14' to parameter: 1
13:58:14,359 DEBUG StringType:59 - binding 'smart' to parameter: 2
13:58:14,359 DEBUG IntegerType:59 - binding '1' to parameter: 3
13:58:14,359 DEBUG TimestampType:59 - binding '2005-04-20 13:31:20' to parameter: 4
While the Thread is sleeping... I use sqlplus to execute...
update hb_patient
set FIRST_NAME = 'changed' , LASTUPD = sysdate
where id = 1;
commit;
Afterwards I query the row and the data is set from the sqlplus statement as expected. The hibernate update did not update the row as expected.
|