天天看點

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環境,建表同對表的操作不宜在一個“事務”中完成;

以上分析還未找到理論上的答案...