欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException

程序员文章站 2022-03-15 08:30:27
...

项目是java web;

使用框架:struts,hibernate,spring;

构建工具:maven

使用一个商品管理系统,用于管理超市商品

 

项目结构如下:
org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException
            
    
    博客分类: JavaJava Web hibernate删除对象瞬态HibernateOptimisticLockingspringframework
 执行如下操作时报错
org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException
            
    
    博客分类: JavaJava Web hibernate删除对象瞬态HibernateOptimisticLockingspringframework
 点击“delete”,删除超市时,报错。

注意:是有时候报错,不是每次删除都报错。

报错信息如下:

Struts Problem Report

Struts has detected an unhandled exception:
Messages: 	

    Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    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

File: 	org/hibernate/jdbc/Expectations.java
Line number: 	81
Stacktraces
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

    org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:181)
    org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:680)
    org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:562)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    com.shop.jn.dao.SupermarketDao$$EnhancerByCGLIB$$2c3435ff.delete()
    com.shop.jn.action.supermarket.DeleteSupermarketAction.execute(DeleteSupermarketAction.java:20)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:453)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:292)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:255)
    com.shop.jn.interceptor.LoggerInterceptor.intercept(LoggerInterceptor.java:23)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:236)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:236)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:90)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:511)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
    org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
    org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
    java.lang.Thread.run(Thread.java:662)
    

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

 

原因分析

执行删除超市的action 是DeleteSupermarketAction,内容如下:

package com.shop.jn.action.supermarket;

import com.opensymphony.xwork2.ActionSupport;
import com.shop.jn.dao.SupermarketDao;
import com.shop.jn.entity.Supermarket;
/***
 * 删除超市.
 * 
 * @author huangwei
 *
 */
public class DeleteSupermarketAction extends ActionSupport {

	private static final long serialVersionUID = 7753616847784594121L;
	private Supermarket supermarket;
	private SupermarketDao supermarketDao;

	@Override
	public String execute() throws Exception {
		this.supermarketDao.delete(this.supermarket);
		return super.execute();
	}

	public Supermarket getSupermarket() {
		return supermarket;
	}

	public void setSupermarket(Supermarket supermarket) {
		this.supermarket = supermarket;
	}

	public SupermarketDao getSupermarketDao() {
		return supermarketDao;
	}

	public void setSupermarketDao(SupermarketDao supermarketDao) {
		this.supermarketDao = supermarketDao;
	}
	
}

 说明:supermarket 是通过依赖注入的,注入的字段是id(http://localhost:8080/shop_goods/supermarket/deleteSupermarket.action?supermarket.id=9)。

此时supermarket 的状态是detached 脱管的(脱离管理的),this.supermarketDao.delete 的方法体如下:

this.sessionFactory.getCurrentSession().delete(obj);

但是hibernate api中对delete 的方法说明如下:

void

delete(Object object) 
          Remove a persistent instance from the datastore.

 要求参数必须是persistent 持久化的的状态。

 

如何解决呢?

使用原生的sql语句

我在dao中新增了一个方法:

public void deleteHQL(int id) {
		this.sessionFactory.getCurrentSession()
				.createQuery("delete from Supermarket where id=?")
				.setInteger(0, id).executeUpdate();
	}

 在DeleteSupermarketAction 中调用如下:

@Override
	public String execute() throws Exception {
		this.supermarketDao.deleteHQL(this.supermarket.getId());
		return super.execute();
	}

 

  • org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException
            
    
    博客分类: JavaJava Web hibernate删除对象瞬态HibernateOptimisticLockingspringframework
  • 大小: 65.2 KB
  • org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException
            
    
    博客分类: JavaJava Web hibernate删除对象瞬态HibernateOptimisticLockingspringframework
  • 大小: 32.1 KB