Well all I can recount is what I do and maybe that might help.
For example, I have an entity Organisation with org_id as primary key and name as (not null) attribute. I also have a version_number column for this entity. The bean looks like:
Code:
public class Organisation
{
private long orgId = 0;
private String name = null;
...
/**
*
* @hibernate.id generator-class="assigned" column="org_id" type="long"
* unsaved-value="0"
*/
public long getOrgId()
...
/**
* @hibernate.version column="version_number" type="integer"
*/
public int getVersionNumber()
Now I have a session facade (since all of this runs inside JBoss and the facade is from my previous EJB project, being reused here).
Code:
public class OrganisationServiceBean implements javax.ejb.SessionBean
{
...
/**
*
* @ejb.interface-method view-type="both"
* @ejb.transaction type="Required"
*/
public int updateOrganisation(Session session, long org_id, String name, int version_number)
{
Organisation organisation = null;
try
{
organisation = (Organisation) session.get(Organisation.class, new Long(org_id));
1 if (organisation != null)
{
2 if (version_number != organisation.getVersionNumber())
{
throw new StaleObjectStateException(Organisation.class, new Long(org_id));
}
3 organisation.setName(name);
session.saveOrUpdate(organisation);
return 1;
}
return 0;
}
catch (Exception e)
{
throw new EJBException(e);
}
finally
{
organisation = null;
}
}
Test 1:
Now if I pause the code at line marked 1, use another unit test to update the same row, and then proceed with continue on the above paused thread:
- The version number check is not violated, but the "saveOrUpdate" throws a StaleObjectException.
Test 2:
However if I pause the code somewhere higher up (after the data has been got previously using another session) and then used another Unit test thread to updated the same row, its my
Code:
if (version_number != organisation.getVersionNumber())
bit of code that detects version violation.
Test 2 simulates a scenario where the data has been obtained in a previous session (followed by closing the transaction) when requested by a UI.
In this situation I think one has to manually check for version_number compatibility. If for some reason, the code passes the compatibility test at line 2 but, say, another thread updates the same row between lines 2 & 3, a StaleObjectException would still be thrown by Hibernate when saveOrUpdate is called. This is is not dissimilar to my EJB (JBoss 3.2.6) deployment anyway.
Of course in my case all of the above happens inside JBoss (4.0.1RC2).
Sorry about the length of this post but I hope it helps in some way (and I was rather hoping that someone, more in the know, would verify my take on Hibernate's behaviour).
Cheers
-raj