一个SSH项目
Spring3 Hibernate3.3.2 Struts2 mysql5.0
以前运行是正常的 ,现在要求数据库换成mysql5.6+
我把之前数据库的建表语句和初始数据导出来,再导入到新的数据库(使用navicat for mysql导入没有错误)
可是正常启动后,只要有插入或修改数据操作时,就会报错:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.pl.domain.Stage#402881455972d669015972e334680006] at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1782) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425) at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2325) at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2625) at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:319) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
本项目在Hibernate的映射文件和数据表中使用了数据版本字段:version。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.pl.domain.Game" table="game"> <id name="id" type="java.lang.String"> <column name="id" /> <generator class="uuid" /> </id> <timestamp name="version" column="version"></timestamp> <many-to-one name="rule" class="com.pl.domain.Rule" fetch="select"> <column name="rid" /> </many-to-one> <many-to-one name="level" class="com.pl.domain.Level" fetch="select"> <column name="level" /> </many-to-one> <many-to-one name="gametype" class="com.pl.domain.Type" fetch="select"> <column name="gametype" /> </many-to-one> <many-to-one name="gamesystem" class="com.pl.domain.Type" fetch="select"> <column name="gamesystem" /> </many-to-one> <many-to-one name="city" class="com.pl.domain.City" fetch="select"> <column name="city" /> </many-to-one> <many-to-one name="pgame" class="com.pl.domain.Game" fetch="select"> <column name="pid" /> </many-to-one> <property name="entry" type="java.lang.Integer"> <column name="entry" length="1" /> </property> <property name="createtime" type="java.util.Date"> <column name="createtime"/> </property> <property name="way" type="java.lang.Integer"> <column name="way" length="1" /> </property> <property name="no" type="java.lang.String"> <column name="NO" length="20" /> </property> <property name="unit" type="java.lang.String"> <column name="unit" length="225" /> </property> <property name="reward" type="java.lang.String"> <column name="reward" length="225" /> </property> <property name="name" type="java.lang.String"> <column name="name" length="20" /> </property> <property name="startdate" type="java.util.Date"> <column name="startdate" length="10" /> </property> <property name="enddate" type="java.util.Date"> <column name="enddate" length="10" /> </property> <property name="status" type="java.lang.Integer"> <column name="status" /> </property> <property name="aim" type="java.lang.String"> <column name="aim" length="65535" /> </property> <property name="vision" type="java.lang.Integer"> <column name="vision" /> </property> <property name="rankrule" type="java.lang.String"> <column name="rankrule"/> </property> <property name="grouprule" type="java.lang.String"> <column name="grouprule"/> </property> <property name="mf" type="java.lang.String"> <column name="mf"/> </property> <property name="ml" type="java.lang.String"> <column name="ml"/> </property> <property name="nf" type="java.lang.String"> <column name="nf"/> </property> <property name="nl" type="java.lang.String"> <column name="nl"/> </property> <property name="nif" type="java.lang.String"> <column name="nif"/> </property> <property name="nil" type="java.lang.String"> <column name="nil"/> </property> <property name="outtitle" type="java.lang.Integer"> <column name="outtitle"/> </property> <property name="isleague" type="java.lang.Integer"> <column name="isleague"/> </property> <property name="ispause" type="java.lang.Integer"> <column name="ispause"/> </property> <set name="stages" cascade="all" inverse="true" lazy="false"> <key> <column name="gid" /> </key> <one-to-many class="com.pl.domain.Stage" /> </set> </class> </hibernate-mapping>
网上查的好像是乐观锁定失败,可是网上别人的错误原因跟我的情况不一样, 不知道怎么解决:
这个是spring的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!--Properties Config Post Processor--> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="/WEB-INF/Configuration.properties" /> </bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClass}"> </property> <property name="jdbcUrl"> <value>${jdbc.url}</value> </property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> <!-- 连接池中保留的最小连接数。 --> <property name="minPoolSize"> <value>10</value> </property> <!-- 连接池中保留的最大连接数。Default:15 --> <property name="maxPoolSize"> <value>10</value> </property> <!-- 初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize"> <value>5</value> </property> <!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime"> <value>60</value> </property> <!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement"> <value>5</value> </property> <!-- 1. JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 2. 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 --> <property name="maxStatements"> <value>0</value> </property> <!-- 每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod"> <value>60</value> </property> <!-- 定义在从数据库获取新连接失败后重复尝试的次数 Default: 30 --> <property name="acquireRetryAttempts"> <value>30</value> </property> <!-- 1. 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 2. 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false --> <property name="breakAfterAcquireFailure"> <value>true</value> </property> <!-- 1. 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 2. 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false --> <property name="testConnectionOnCheckout"> <value>false</value> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <!-- 批处理 --> <prop key="hibernate.jdbc.batch_size">5</prop> <!-- 开启缓存 --> <prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </prop> <prop key="cache.use_second_level_cache">true</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value>classpath:/com/pl/domain</value> </list> </property> </bean> <bean id="tdataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClass}"> </property> <property name="jdbcUrl"> <value>${jdbc.turl}</value> </property> <property name="user" value="${jdbc.tusername}"></property> <property name="password" value="${jdbc.tpassword}"></property> <property name="minPoolSize"> <value>5</value> </property> <property name="maxPoolSize"> <value>10</value> </property> <property name="initialPoolSize"> <value>1</value> </property> <property name="maxIdleTime"> <value>60</value> </property> <property name="acquireIncrement"> <value>5</value> </property> <property name="maxStatements"> <value>0</value> </property> <property name="idleConnectionTestPeriod"> <value>60</value> </property> <property name="acquireRetryAttempts"> <value>30</value> </property> <property name="breakAfterAcquireFailure"> <value>true</value> </property> <property name="testConnectionOnCheckout"> <value>false</value> </property> </bean> <bean id="tsessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="tdataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <!-- 批处理 --> <prop key="hibernate.jdbc.batch_size">5</prop> <!-- 开启缓存 --> <prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </prop> <prop key="cache.use_second_level_cache">true</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value>classpath:/com/pl/domain</value> </list> </property> </bean> <!-- 事务处理设置 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory" /> </property> </bean> <bean id="ttransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="tsessionFactory" /> </property> </bean> <!-- 所有方法使用PROPAGATION_REQUIRED类型的事务 --> <bean id="interceptorTransaction" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref local="transactionManager" /> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="tinterceptorTransaction" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref local="ttransactionManager" /> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <!-- 管理所有以Service结尾的Bean --> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <list> <value>interceptorTransaction</value> <value>tinterceptorTransaction</value> <value>interceptoruploadTransaction</value> </list> </property> </bean> <!-- 服务器datasource --> <bean id="sessionFactorymain" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource1" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.cglib.use_reflection_optimizer">false</prop> <prop key="hibernate.jdbc.fetch_size">50</prop> <prop key="hibernate.jdbc.batch_size">20</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value>classpath:/com/pl/pojo</value> </list> </property> </bean> <bean id="transactionuploadManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactorymain" /> </property> </bean> <bean id="interceptoruploadTransaction" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref local="transactionuploadManager" /> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClass}"> </property> <property name="jdbcUrl"> <value>${jdbc.url}</value> </property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> <property name="minPoolSize"> <value>5</value> </property> <property name="maxPoolSize"> <value>10</value> </property> <property name="initialPoolSize"> <value>5</value> </property> <property name="maxIdleTime"> <value>60</value> </property> <property name="acquireIncrement"> <value>5</value> </property> <property name="maxStatements"> <value>0</value> </property> <property name="idleConnectionTestPeriod"> <value>60</value> </property> <property name="acquireRetryAttempts"> <value>30</value> </property> <property name="breakAfterAcquireFailure"> <value>true</value> </property> <property name="testConnectionOnCheckout"> <value>false</value> </property> </bean> </beans>
<p>
<br>
</p>
<p>
<br>
</p>
经过3天欲仙欲死爬坑,自己已经解决了这个问题。
记录到博客中: https://my.oschina.net/iyinghui/blog/822592
好多早年不规范埋的雷。SSH+mysql==连环坑版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。