Hi I have the strangest problem at the moment. In order to maintain data integrity in our multiuser environment we are using row version number protocol. However while performing midlle-to-large scale database updates we get hibernate returning objects (lazily loaded) with version numbers massively different from those currently held in the database. When the bug got reported (users get message telling them their data is out of date and to refresh their screen) we assumed it was a coding error - i.e. that we were perhaps asking for the wrong version of the object. However unfortunately that isn't the case. For example a 'SUBSCRIBER' has a 1:1 relationship with it's 'DIRECTROUTING' and we want to delete this subscribers' direct routing. We first call a load on the direct routing object with a provided id, and then then we check the version of the returned object with the last known version the UI received. Usually this is fine, however after say doing this 200 times in a row hibernate will all of a sudden say the object from the database has a version number of 428 and the one out UI had was only version number 2, and then throws an exception to state this. However if we look in the Db we see that the version number queried for was the correct number - but hibernate's version number was entirely wrong?? I am not assuming it is a bug in hibernate and is more likely something we are doing wrong in loading the objects or something, but I am stuck as I have a customer SLA to meet and have no idea what to do?? Ideas? Thanks!
Hibernate version:3
Mapping documents: Subscriber includes: <one-to-one name="directRouting" class="DirectRouting" property-ref="subscriber" cascade="save-update, delete" />
DirectRouting includes: <many-to-one name="subscriber" column="SUBSCRIBER_ID" unique="true" class="Subscriber" cascade="none"/>
Code between sessionFactory.openSession() and session.close(): Using JTA
Full stack trace of any exception that occurs: None as exception is created by us after the 'version' failure occurs
Name and version of the database you are using: Oracle 8i
Code: /** * Utility method to load this object from hibernate and check the * versions are correct before it is worked on. * @param baseModel <code>Class</code> this is the class of the object * being requested. It should be a specialised class of sub-class * <code>BaseModel</code> * @param id <code>String</code> the id of the object being asked for. * @param version int this is the version being asked for. Does not neccesarily * reflect the actual version of the persistent object - if not the same then * the excpetion is thrown to represent that. * @throws NamingException from <code>InitalContext</code>. * @throws StaleObjectStateException if the version asked for is different * to the peristent version (i.e. the version stored in the database). This * is an implementation of application versioning specified in the Hibernate * user manual. * @return <code>BaseModel</code> of the type requested in the <blockquote> * parameter <i>baseModel</i> </blockquote>. */ public BaseModel load(Class baseModel, String id, int version) throws NamingException, StaleObjectStateException { BaseModel model = (BaseModel) this.currentSession().load(baseModel, id); if(model.getVersion() != version) { //not the same so tell user throw new StaleObjectStateException(baseModel.getName(), id); } return model; }
Thanks in advance
|