Java 捕获休眠异常

Java 捕获休眠异常,java,hibernate,exception,Java,Hibernate,Exception,我有一个@存储库,如下所示: @Repository public class OrderRepository { @Autowired SessionFactory sessionFactory; public void update(Order order) { sessionFactory.getCurrentSession().update(order); } } @Transactional @Service public cl

我有一个
@存储库
,如下所示:

@Repository
public class OrderRepository  {

    @Autowired
    SessionFactory sessionFactory;

    public void update(Order order) {

        sessionFactory.getCurrentSession().update(order);
    }
}
@Transactional
@Service
public class OrderService {

    @Autowired
    OrderRepository orderRepository;

    public void updateOrder(Order order) {

        orderRepository.update(order);
    }
}
它由
@服务调用,如下所示:

@Repository
public class OrderRepository  {

    @Autowired
    SessionFactory sessionFactory;

    public void update(Order order) {

        sessionFactory.getCurrentSession().update(order);
    }
}
@Transactional
@Service
public class OrderService {

    @Autowired
    OrderRepository orderRepository;

    public void updateOrder(Order order) {

        orderRepository.update(order);
    }
}
在某些情况下,正在更新的订单已从数据库中删除(这是预期的,并且是良性的)。发生这种情况时,将引发异常:

SEVERE: Servlet.service() for servlet [DispatcherServlet] in context with path [/project] threw exception [Request processing failed; nested exception is org.springframework.orm.hibernate4.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] with root cause
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:81)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:63)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3281)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525)
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:159)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:555)
    at org.springframework.transaction.support.AbstractOrderTransactionManager.processCommit(AbstractOrderTransactionManager.java:757)
    at org.springframework.transaction.support.AbstractOrderTransactionManager.commit(AbstractOrderTransactionManager.java:726)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
    at uk.co.domain.services.OrderService$$EnhancerBySpringCGLIB$$35a2d392.updateOrder(<generated>)
    at uk.co.domain.controllers.OrderController.test(RequestController.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
遗憾的是,它不起作用,用户仍然看到异常。我还尝试捕获了
hibernateeexception
stalestateeexception
,这两种方法都不起作用


我尝试将相同的try/catch添加到服务而不是存储库中,但这不起作用。如果有任何提示,我将不胜感激。

实际的更新查询是在刷新时执行的。在会话中调用update()时不会出现这种情况。在这种特殊情况下,刷新发生在提交服务方法调用的事务包装之前。顺便说一句,可以在堆栈跟踪中看到:

at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
因此,如果要捕获异常,应在服务外部捕获它:

try {
    orderService.updateOrder(order);
}
catch (ConcurrencyFailureException e) {
    ...
}

即使从服务或DAO方法内部显式地flush(),捕获异常也是一个坏主意,因为它会使Hibernate会话处于不可靠的状态。应回滚事务,并立即关闭会话。如果让异常冒泡,则会自动发生这种情况,因此最好在调用服务的代码中捕获异常。

实际的更新查询在刷新时执行。在会话中调用update()时不会出现这种情况。在这种特殊情况下,刷新发生在提交服务方法调用的事务包装之前。顺便说一句,可以在堆栈跟踪中看到:

at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
因此,如果要捕获异常,应在服务外部捕获它:

try {
    orderService.updateOrder(order);
}
catch (ConcurrencyFailureException e) {
    ...
}

即使从服务或DAO方法内部显式地flush(),捕获异常也是一个坏主意,因为它会使Hibernate会话处于不可靠的状态。应回滚事务,并立即关闭会话。如果您让异常冒泡,则会自动发生这种情况,因此您最好在调用服务的代码中捕获它。

感谢您的清晰解释,非常有意义,并且完全按照描述工作。感谢您的清晰解释,非常有意义,并且完全按照描述工作。