首页 > 代码库 > Error while commiting the transaction问题

Error while commiting the transaction问题

在搭建一个spring3.0+hibernate+jpa项目框架,根据网友提供的例子,在junit下做了一个存储数据的测试,报如下异常:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while commiting the transaction

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)

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:394)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)

at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)

at com.alcor.test.service.TestaService$$EnhancerByCGLIB$$41631835.add(<generated>)

at com.alcor.test.junit.TestUnit.testTransaction(TestUnit.java:36)

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:601)

at junit.framework.TestCase.runTest(TestCase.java:168)

at junit.framework.TestCase.runBare(TestCase.java:134)

at junit.framework.TestResult$1.protect(TestResult.java:110)

at junit.framework.TestResult.runProtected(TestResult.java:128)

at junit.framework.TestResult.run(TestResult.java:113)

at junit.framework.TestCase.run(TestCase.java:124)

at junit.framework.TestSuite.runTest(TestSuite.java:232)

at junit.framework.TestSuite.run(TestSuite.java:227)

at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Caused by: javax.persistence.RollbackException: Error while commiting the transaction

at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)

... 27 more

Caused by: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)

at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)

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.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)

... 28 more

Caused by: java.sql.BatchUpdateException: Table ‘j2ee.student‘ doesn‘t exist

at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2007)

at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1443)

at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)

at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)

at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)

... 36 more


网上搜索了一阵,没什么收获。还是自己解决吧。逐层分析异常堆栈如下:

Caused by: java.sql.BatchUpdateException: Table ‘j2ee.student‘ doesn‘t exist;   Caused by: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update;

Caused by: javax.persistence.RollbackException: Error while commiting the transaction;

猜测问题的原因可能是因为:insert一条记录,正常情况下,如果表不存在,则会创建表,然后insert记录。这里因为是junit环境,且表不存在,在一个“事务”环境中,要建表、insert记录,因为什么原因,建表失败。导致Insert失败。

为了验证这个测试,手动建表,然后执行该junit测试操作,insert成功;

删除表,在正常环境下启动web服务器,成功启动后表即被建立,然后对该表的操作都成功。

到这里,初步得出一个结论,jap+hibernate+spring环境,建表同对表的操作不宜在一个“事务”中完成;

以上分析还未找到理论上的答案...