从 Hibernate 乐观锁定异常中恢复
Recover from Hibernate Optimistic Locking exception
最近我遇到了一个奇怪的问题。我试图优雅地处理陈旧状态异常。但是在 catch 块中它仍然抛出异常。以下是代码片段
public void saveObject(Object ob){
try{
sessionFactory.getCurrentSession().saveOrUpdate(ob);
}catch(org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException e){
object latestObject = // get latest object from db;
copyFieldsFromObToLatestObject(ob,latestObject);
// print the version of of both object
LOGGER.info(" ui_version="+ob.getVersion().longValue()+"
entity_version="+latestObject.getVersion().longValue());
// the ui _version is less than entity_ version as expected
sessionFactory.getCurrentSession().saveOrUpdate(latestObject); // at this line I still get the same optimistic locking exception
}
}
/**
ob2 is the latest object which contains the correct version hence copying the fields from previous object to this latest object
**/
private void copyFieldsFromObToLatestObject(ob1,ob2){
ob2.setA(ob1.getA())..
so on
}
有人可以看看这个吗。我无法得到正确处理后仍然抛出乐观锁定异常的原因
编辑 1:堆栈跟踪:
org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
[INFO] at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:283)
[INFO] at org.springframework.orm.hibernate5.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:755)
[INFO] at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:590)
[INFO] at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
[INFO] at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
[INFO] at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
[INFO] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
[INFO] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
[INFO] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
[INFO] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
[INFO] at com.sun.proxy.$Proxy155.saveOrUpdate(Unknown Source)
[INFO] at biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.handleStaleStateException(AppointmentServiceExtension1BOImpl.java:1520)
[INFO] at biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.saveSAR(AppointmentServiceExtension1BOImpl.java:845)
[INFO] at biz.kaar.common.services.DBServiceImpl.saveSAR(DBServiceImpl.java:382)
[INFO] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[INFO] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[INFO] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[INFO] at java.lang.reflect.Method.invoke(Method.java:498)
[INFO] at net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:115)
[INFO] at biz.kaar.common.security.AuthorizedGWTServlet.processCall(AuthorizedGWTServlet.java:252)
[INFO] at biz.kaar.common.services.RemoteServletWithLogging.processCall(RemoteServletWithLogging.java:90)
[INFO] at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373)
[INFO] at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
[INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
[INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
[INFO] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
[INFO] at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
[INFO] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
[INFO] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityIntercep
在 catch 块中,您应该捕获抛出并要处理的异常。你抓到 Optimistic locking exception
。我什至无法想象这是如何编译的。尝试用堆栈跟踪中的异常名称替换它?
问题已解决,我还在 to 字段中复制关联子实体的版本,这导致旧版本的子实体被保存,从而导致错误
最近我遇到了一个奇怪的问题。我试图优雅地处理陈旧状态异常。但是在 catch 块中它仍然抛出异常。以下是代码片段
public void saveObject(Object ob){
try{
sessionFactory.getCurrentSession().saveOrUpdate(ob);
}catch(org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException e){
object latestObject = // get latest object from db;
copyFieldsFromObToLatestObject(ob,latestObject);
// print the version of of both object
LOGGER.info(" ui_version="+ob.getVersion().longValue()+"
entity_version="+latestObject.getVersion().longValue());
// the ui _version is less than entity_ version as expected
sessionFactory.getCurrentSession().saveOrUpdate(latestObject); // at this line I still get the same optimistic locking exception
}
}
/**
ob2 is the latest object which contains the correct version hence copying the fields from previous object to this latest object
**/
private void copyFieldsFromObToLatestObject(ob1,ob2){
ob2.setA(ob1.getA())..
so on
}
有人可以看看这个吗。我无法得到正确处理后仍然抛出乐观锁定异常的原因
编辑 1:堆栈跟踪:
org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 [INFO] at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:283) [INFO] at org.springframework.orm.hibernate5.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:755) [INFO] at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:590) [INFO] at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765) [INFO] at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734) [INFO] at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518) [INFO] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) [INFO] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [INFO] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [INFO] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [INFO] at com.sun.proxy.$Proxy155.saveOrUpdate(Unknown Source) [INFO] at biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.handleStaleStateException(AppointmentServiceExtension1BOImpl.java:1520) [INFO] at biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.saveSAR(AppointmentServiceExtension1BOImpl.java:845) [INFO] at biz.kaar.common.services.DBServiceImpl.saveSAR(DBServiceImpl.java:382) [INFO] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [INFO] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [INFO] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [INFO] at java.lang.reflect.Method.invoke(Method.java:498) [INFO] at net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:115) [INFO] at biz.kaar.common.security.AuthorizedGWTServlet.processCall(AuthorizedGWTServlet.java:252) [INFO] at biz.kaar.common.services.RemoteServletWithLogging.processCall(RemoteServletWithLogging.java:90) [INFO] at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373) [INFO] at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [INFO] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) [INFO] at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [INFO] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) [INFO] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityIntercep
在 catch 块中,您应该捕获抛出并要处理的异常。你抓到 Optimistic locking exception
。我什至无法想象这是如何编译的。尝试用堆栈跟踪中的异常名称替换它?
问题已解决,我还在 to 字段中复制关联子实体的版本,这导致旧版本的子实体被保存,从而导致错误