I am attempting to use the "version" mapping to indicate to hibernate the state of the Employee object that I have mapped. I use a composite-id for the key to a legacy database. The key consistes of two properties fiscalYear and documentNumber. I also map a "version" property that has a column in the database named "LOG_COUNTER". I want to use Hibernate's automatic versioning to handle the state of my objects but every time I execute Hibernate's saveOrUpdate method after having populated my Employee object with test data I get an ObjectStaleStateException.
I am using Spring in this application. So I make use of the HibernateTemplate to execute Hibernate's built-in methods.
Code:
public void saveEmployee(Employee employee) {
this.getHibernateTemplate().saveOrUpdate(employee);
}
The wiring of everything in the application has been tested thoroughly and is solid. I feel like I must be mapping the "version" or the "composite-id" incorrectly. Is there anything I must do to the version attribute of the Employee class before calling the saveOrUpdate method?
Thanks in advance,
Christopher Kwiatkowski
Hibernate version:2.1.6 Mapping documents:Code:
<hibernate-mapping>
<class name="org.appfuse.model.Employee" table="bbab20e" lazy="true">
<composite-id name="documentId" class="org.appfuse.model.DocumentId">
<key-property name="fiscalYear"
column="BBAB20E_CDFSYR"
type="string"/>
<key-property name="documentNumber"
column="BBAB20E_NODOCU"
type="string"/>
</composite-id>
<version name="version" column="LOG_COUNTER" unsaved-value="null"/>
<property name="firstName" column="BBAB20E_NMEMFS" />
<property name="lastName" column="BBAB20E_NMEMLS" />
<property name="gender" column="BBAB20E_CDSEX"/>
<property name="middleName" column="BBAB20E_NMEMMD" not-null="false"/>
<property name="suffix" column="BBAB20E_NMEMSF" not-null="false"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Full stack trace of any exception that occurs:Code:
[junit] ------------- ---------------- ---------------
[junit] Testcase: testSaveEmployee(org.appfuse.service.EmployeeManagerTest):
Caused an ERROR
[junit] Row was updated or deleted by another transaction (or unsaved-value
mapping was incorrect) for org.appfuse.model.Employee instance with identifier:
org.appfuse.model.DocumentId@d0220c[
[junit] fiscalYear=9999
[junit] documentNumber=999990003
[junit] ]; nested exception is net.sf.hibernate.StaleObjectStateException: R
ow was updated or deleted by another transaction (or unsaved-value mapping was i
ncorrect) for org.appfuse.model.Employee instance with identifier: org.appfuse.m
odel.DocumentId@d0220c[
[junit] fiscalYear=9999
[junit] documentNumber=999990003
[junit] ]
[junit] org.springframework.orm.hibernate.HibernateOptimisticLockingFailureE
xception: Row was updated or deleted by another transaction (or unsaved-value ma
pping was incorrect) for org.appfuse.model.Employee instance with identifier: or
g.appfuse.model.DocumentId@d0220c[
[junit] fiscalYear=9999
[junit] documentNumber=999990003
[junit] ]; nested exception is net.sf.hibernate.StaleObjectStateException: R
ow was updated or deleted by another transaction (or unsaved-value mapping was i
ncorrect) for org.appfuse.model.Employee instance with identifier: org.appfuse.m
odel.DocumentId@d0220c[
[junit] fiscalYear=9999
[junit] documentNumber=999990003
[junit] ]
[junit] net.sf.hibernate.StaleObjectStateException: Row was updated or delet
ed by another transaction (or unsaved-value mapping was incorrect) for org.appfu
se.model.Employee instance with identifier: org.appfuse.model.DocumentId@d0220c[
[junit] fiscalYear=9999
[junit] documentNumber=999990003
[junit] ]
[junit] at net.sf.hibernate.persister.AbstractEntityPersister.check(Abst
ractEntityPersister.java:501)
[junit] at net.sf.hibernate.persister.EntityPersister.update(EntityPersi
ster.java:672)
[junit] at net.sf.hibernate.persister.EntityPersister.update(EntityPersi
ster.java:642)
[junit] at net.sf.hibernate.impl.ScheduledUpdate.execute(ScheduledUpdate
.java:52)
[junit] at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java
:2414)
[junit] at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:23
68)
[junit] at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2236
)
[junit] at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTrans
action.java:61)
[junit] at org.springframework.orm.hibernate.HibernateTransactionManager
.doCommit(HibernateTransactionManager.java:386)
[junit] at org.springframework.transaction.support.AbstractPlatformTrans
actionManager.commit(AbstractPlatformTransactionManager.java:316)
[junit] at org.springframework.transaction.interceptor.TransactionInterc
eptor.invoke(TransactionInterceptor.java:211)
[junit] at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:138)
[junit] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(J
dkDynamicAopProxy.java:148)
[junit] at $Proxy0.saveEmployee(Unknown Source)
[junit] at org.appfuse.service.EmployeeManagerTest.testSaveEmployee(Empl
oyeeManagerTest.java:73)
[junit] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[junit] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces
sorImpl.java:39)
[junit] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
hodAccessorImpl.java:25)
Name and version of the database you are using:mysql-4.0.18-win
mysql-connector-java-3.0.11-stable
The generated SQL (show_sql=true): [junit] ------------- Standard Output ---------------
[junit] Hibernate: update bbab20e set LOG_COUNTER=?, BBAB20E_NMEMFS=?, BBAB2
0E_NMEMLS=?, BBAB20E_CDSEX=?, BBAB20E_NMEMMD=?, BBAB20E_NMEMSF=?, BBAB20E_TXSTR1
=?, BBAB20E_TXSTR2=?, BBAB20E_TXCTHM=?, BBAB20E_TXSTHM=?, BBAB20E_CDZPHM=?, BBAB
20E_NOBLDG=?, BBAB20E_NMBLDG=?, BBAB20E_NOFLOR=?, BBAB20E_NOROOM=?, BBAB20E_NOPH
HM=?, BBAB20E_NOPHOF=? where BBAB20E_CDFSYR=? and BBAB20E_NODOCU=? and LOG_COUNT
ER=?
[junit] Hibernate: select employee0_.BBAB20E_CDFSYR as BBAB20E_1_0_, employe
e0_.BBAB20E_NODOCU as BBAB20E_2_0_, employee0_.LOG_COUNTER as LOG_COUN3_0_, empl
oyee0_.BBAB20E_NMEMFS as BBAB20E_4_0_, employee0_.BBAB20E_NMEMLS as BBAB20E_5_0_
, employee0_.BBAB20E_CDSEX as BBAB20E_6_0_, employee0_.BBAB20E_NMEMMD as BBAB20E
_7_0_, employee0_.BBAB20E_NMEMSF as BBAB20E_8_0_, employee0_.BBAB20E_TXSTR1 as B
BAB20E_9_0_, employee0_.BBAB20E_TXSTR2 as BBAB20E10_0_, employee0_.BBAB20E_TXCTH
M as BBAB20E11_0_, employee0_.BBAB20E_TXSTHM as BBAB20E12_0_, employee0_.BBAB20E
_CDZPHM as BBAB20E13_0_, employee0_.BBAB20E_NOBLDG as BBAB20E14_0_, employee0_.B
BAB20E_NMBLDG as BBAB20E15_0_, employee0_.BBAB20E_NOFLOR as BBAB20E16_0_, employ
ee0_.BBAB20E_NOROOM as BBAB20E17_0_, employee0_.BBAB20E_NOPHHM as BBAB20E18_0_,
employee0_.BBAB20E_NOPHOF as BBAB20E19_0_ from bbab20e employee0_ where employee
0_.BBAB20E_CDFSYR=? and employee0_.BBAB20E_NODOCU=?
Debug level Hibernate log excerpt:[/code]