Reputation: 213
In my code I am saving data to a Microsoft SQL database version 10.50.4042.0 I am using hibernate-validator version 4.2.0.CR1 and hibernate-commons-annotations version 3.2.0.Final
I am working over several projects connected by Maven built on Spring framework.In my test project(using junit 4.8.2) I am trying to save the data into the database by selecting several xml files and converting them into database rows(one row at a time). Inside my project that is dealing with SQL transactions I am sending the data to the database using this annotation
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
I think the problem occurs inside the Transactional process of hibernate.But there are no asynchronized calls and XML structure is totally valid. I tried different approaches but the problem seems to occur very randomly without any specific pattern and it fails to save only 1 random data row.
Error message I get is:
2016-06-09 12:41:01,578: ERROR [http-8080-Processor3] Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:47)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2574)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2478)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2805)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:114)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy48.save(Unknown Source)
There are no other SQL calls that are updating the row at the same time. Can you help if you came across the same problem in hibernate.Or any other suggestions might help. Thank you
Upvotes: 4
Views: 552
Reputation: 29168
Actually this problem means that
It was unable to found record with your given id.
To avoid this I always read record with same id if I found record back then I call update otherwise throw "exception record not found"
.
You have deleted a object and then tried to update it. On that case, you need to clear the session session.clear();
In the Hibernate mapping file for the id
property, if you use any generator class, for that property you should not set the value explicitly by using a setter method.
If you set the value of the Id property explicitly, it will lead the error above. Check this to avoid this error.
However, to get a better handle as to what causes the problem, try the following:
set hibernate.show_sql to true
.
This should show you the SQL that is executed and causes the
problem.log levels for Spring and Hibernate to DEBUG
, again this
will give you a better idea as to which line causes the problem.This Exception will arise in different scenario of save and saveOrupdate method of hibernate.
if Object is transient , need to save may occur this exception Conditions.
Object Doesn’t Exist: This is the most easy to determine : has the object get deleted somehow? If so, trying to delete once again it will throw this exception.
Object is Stale: Hibernate caches objects from the session. If the object was modified, and Hibernate doesn’t know about it, it will throw this exception — note the StaleStateException
part of the exception.
so after committing the object to database need to flush
or clear
or clean
it ,not before.
Upvotes: 2
Reputation: 2128
Reading your explanation it seems also to me that is a problem related to the isolation level of your trasaction.
The READ_COMMITTED isolation level specify that it is possible to have access only to records not comprehended in an open transaction, so I think that in your case, it randomly happens that one other transaction accesses to one or plus of your records that are batch updated, and so it raises an exception.
I think that one solution is, giving a committ each row by time, verify each time the row's db state, or instead, you may manage this exception in a way to avoid halting of your process or transaction.
Upvotes: 1
Reputation: 3943
As far as I know, there can be one of the below mentioned three reasons:
Share your code if none of the three mentioned above solve your issue.
Upvotes: 1