无法提交 Hibernate 事务
Could not commit Hibernate transaction
我是 Hibernate 的新手。我正在尝试编写一个方法来插入或更新 50 条记录,然后提交它,然后再次继续插入。我这样做是因为如果在插入最后一条记录时发生某些事情,我想保留数据库中所有以前的记录。
这就是我正在做的事情:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
if(sessionEnded){//At the very beginning, the transaction remains open dont know why. So session.getTransaction().begin() causing exception
session.getTransaction().begin();
sessionEnded = false;
}
session.saveOrUpdate(storeDetailsDTOTmp);
if ( ++count % 10 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush();
session.clear();
sessionEnded =true;
} else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
这工作正常,但在执行此方法后发生异常。因此,此方法的 return 值从未 return 到调用方法。谁能帮我?堆栈跟踪:
com.follett.fd.exception.UniversityWithSimilarAdoptionException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at com.follett.fd.service.impl.FFDServiceImpl.populateLocation(FFDServiceImpl.java:194) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController.populateLocation(FFDServiceController.java:74) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController$$FastClassBySpringCGLIB$f892fae.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at com.follett.fd.controller.FFDServiceController$$EnhancerBySpringCGLIB$$f350f456.populateLocation(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-embed-core-7.0.30.jar:7.0.30]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
仅当 sessionEnded
为 true
时才打开会话,但仅在 session.getTransaction().commit()
之后才将其设置为 true
。更好的解决方案是在循环外开始和结束会话。
这是您可以在 50 条记录后将记录刷新到 DB 中的代码,但是 committing/rollback 所有这些都是在失败的情况下发生的,这通常是这种情况,但是如果您想提交 50 条记录,那么在清除后执行提交。
public void insert(List<T> items) {
//begin transaction
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
session.save(item);
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
//commit transaction
}
标志检查有误导致交易无法开始。我已经进行了更改,希望这会奏效。
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs)
{
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =true; for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs)
{
if(sessionEnded)
{
session.getTransaction().begin(); sessionEnded = false;
} session.saveOrUpdate(storeDetailsDTOTmp) ;
if ( ++count % 10 == 0 )
{
//If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush(); session.clear();
sessionEnded =true;
}
else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
我已将 @Transactional
置于 class 级别。我相信这是导致问题的原因,但我不确定。删除它后,我在执行时遇到了一些错误:this.hibernateSessionFactory.getCurrentSession();
。我想我必须为此设置一个 属性。
无论如何,为了实现我想要的,我修改了方法:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
session.saveOrUpdate(storeDetailsDTOTmp);
//session.evict(storeDetailsDTOTmp);
if ( ++count % 50 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size.");
session.flush();
session.clear();
}
}
return true;
}
我在插入 50 条记录后调用此方法。请注意,我在修改方法后将 @Transactional
注释保留在 class 级别。
我是 Hibernate 的新手。我正在尝试编写一个方法来插入或更新 50 条记录,然后提交它,然后再次继续插入。我这样做是因为如果在插入最后一条记录时发生某些事情,我想保留数据库中所有以前的记录。
这就是我正在做的事情:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
if(sessionEnded){//At the very beginning, the transaction remains open dont know why. So session.getTransaction().begin() causing exception
session.getTransaction().begin();
sessionEnded = false;
}
session.saveOrUpdate(storeDetailsDTOTmp);
if ( ++count % 10 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush();
session.clear();
sessionEnded =true;
} else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
这工作正常,但在执行此方法后发生异常。因此,此方法的 return 值从未 return 到调用方法。谁能帮我?堆栈跟踪:
com.follett.fd.exception.UniversityWithSimilarAdoptionException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at com.follett.fd.service.impl.FFDServiceImpl.populateLocation(FFDServiceImpl.java:194) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController.populateLocation(FFDServiceController.java:74) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController$$FastClassBySpringCGLIB$f892fae.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at com.follett.fd.controller.FFDServiceController$$EnhancerBySpringCGLIB$$f350f456.populateLocation(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-embed-core-7.0.30.jar:7.0.30]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
仅当 sessionEnded
为 true
时才打开会话,但仅在 session.getTransaction().commit()
之后才将其设置为 true
。更好的解决方案是在循环外开始和结束会话。
这是您可以在 50 条记录后将记录刷新到 DB 中的代码,但是 committing/rollback 所有这些都是在失败的情况下发生的,这通常是这种情况,但是如果您想提交 50 条记录,那么在清除后执行提交。
public void insert(List<T> items) {
//begin transaction
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
session.save(item);
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
//commit transaction
}
标志检查有误导致交易无法开始。我已经进行了更改,希望这会奏效。
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs)
{
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =true; for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs)
{
if(sessionEnded)
{
session.getTransaction().begin(); sessionEnded = false;
} session.saveOrUpdate(storeDetailsDTOTmp) ;
if ( ++count % 10 == 0 )
{
//If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush(); session.clear();
sessionEnded =true;
}
else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
我已将 @Transactional
置于 class 级别。我相信这是导致问题的原因,但我不确定。删除它后,我在执行时遇到了一些错误:this.hibernateSessionFactory.getCurrentSession();
。我想我必须为此设置一个 属性。
无论如何,为了实现我想要的,我修改了方法:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
session.saveOrUpdate(storeDetailsDTOTmp);
//session.evict(storeDetailsDTOTmp);
if ( ++count % 50 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size.");
session.flush();
session.clear();
}
}
return true;
}
我在插入 50 条记录后调用此方法。请注意,我在修改方法后将 @Transactional
注释保留在 class 级别。