簡體   English   中英

無法提交休眠事務

[英]Could not commit Hibernate transaction

我是休眠的新手。 我正在嘗試編寫一種方法,該方法將插入或更新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;
    }

這工作正常,但是執行此方法后發生異常。 因此,此方法的返回值永遠不會返回到調用方法。 誰能幫我? 堆棧跟蹤:

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$$2f892fae.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]

僅當sessionEndedtrue時才打開會話,但僅在session.getTransaction().commit()之后將其設置為true 更好的解決方案是在循環外部開始和結束會話。

我把@Transactional放在了班級。 我不確定這是引起問題的原因,但我不確定。 刪除它之后,我在執行時遇到一些錯誤: 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批注。

謝謝大家的幫助!

這是代碼,您可以在50條記錄之后將記錄刷新到DB中,但是在發生故障的情況下會全部提交/回滾(通常是這種情況),但是如果您要提交50條記錄,則在清除后執行commit。

    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;
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM