title: Spring @Async generates LazyInitializationExceptions
body: <p>The Spring MVC application needs to execute an intensive computation job which takes several minutes. The client wants to run this job in asynchronous way. But after I enable the @Async annotation on the method (see code 1) and get the error (see code 2). My web.xml and web-appliaiton-context.xml are also presented below. I tried to find a workaround to fix this, but failed. Please help.</p>
  
  <p>code 1:</p>
  
  <pre><code>@Service
  public class AsyncServiceImpl implements AsyncServiceInt{
  
      protected int pertArrSize = 1000;
      @Autowired
      protected TblvDao tblvDao1 = null;
  
      @Override
      @Async
      public void startSlowProcess(Integer scenarioId) throws SecurityException, IllegalArgumentException, IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
          batchUpdateSummaryPertSim(scenarioId);
  
      }
  
      public void batchUpdateSummaryPertSim(Integer scenarioId) throws SecurityException, IllegalArgumentException, IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException
      {
          double[] summaryArry = new double[pertArrSize];
          summaryArry = summaryPertSim_env(scenarioId, summaryArry);
      }
  
      @Transactional
      private double[] summaryPertSim_env(Integer  scenarioId,
      double[] summaryArry) throws IOException, ClassNotFoundException, SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
          ScenarioTblv scenario = tblvDao1.getScenarioTblv(scenarioId);
          TblvResultSaved savedResult = scenario.getTblvResultSaved();
          TblvScenarioCategory4 tblvScenarioCategory4 = new TblvScenarioCategory4();
          List&lt;TblvScenarioCategory4&gt; tblvScenarioCategory4List = scenario
          .getTblvScenarioCategory4List();
          Double min = 0.0, max = 0.0, ml = 0.0;
          Integer conf = 4;
          if (savedResult.getEnvDist() != null) {
  
              byte[] st = (byte[]) savedResult.getEnvDist();
              ByteArrayInputStream baip = new ByteArrayInputStream(st);
              ObjectInputStream ois = new ObjectInputStream(baip);
  
              summaryArry = (double[]) ois.readObject();
              } else {
              for (int i = 0; i &lt; tblvScenarioCategory4List.size(); i++) {
                  tblvScenarioCategory4 = tblvScenarioCategory4List.get(i);
  
                  vTblvScenarioEffectChoose v = tblvDao1
                  .getvTblvScenarioEffectChooseById(tblvScenarioCategory4
                  .getId());
  
                  if (v.getC1id() == 1) {
                      tblvScenarioCategory4.setImpactYearlyUnitsSim(pertArrSize);
                      min = tblvScenarioCategory4
                      .getTblvEffectScenarioImpactUnitValue()
                      .getLowValue();
                      max = tblvScenarioCategory4
                      .getTblvEffectScenarioImpactUnitValue()
                      .getHighValue();
                      ml = tblvScenarioCategory4
                      .getTblvEffectScenarioImpactUnitValue()
                      .getMostValue();
                      conf = tblvScenarioCategory4
                      .getTblvEffectScenarioImpactUnitValue().getConf();
                      if ((conf == null) || (conf == 0))
                      conf = 4;
  
                      double[] MOPertArr;
  
                      MOPertArr = getPertArry(min, max, ml, conf, pertArrSize);
  
                      double[] benefitResult = new double[pertArrSize];
  
                      for (int j = 0; j &lt; pertArrSize; j++) {
                          tblvScenarioCategory4.setSimIndex(j);
                          tblvScenarioCategory4
                          .getTblvEffectScenarioImpactUnitValue()
                          .setHighValue(MOPertArr[j]);
                          benefitResult[j] = tblvScenarioCategory4.getHighPvSum();
                          summaryArry[j] = summaryArry[j] + benefitResult[j];
                      }
                      tblvScenarioCategory4
                      .getTblvEffectScenarioImpactUnitValue()
                      .setHighValue(max);
                  }
  
              }
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              ObjectOutputStream oos = new ObjectOutputStream(baos);
              oos.writeObject(summaryArry);
              byte[] summaryArryAsBytes = baos.toByteArray();
              savedResult.setEnvDist(summaryArryAsBytes);
              tblvDao1.saveTblvResultSaved(savedResult);
          }
          return summaryArry;
      }
  </code></pre>
  
  <p>code 2:</p>
  
  <pre><code> 10:26:06,233 ERROR org.hibernate.LazyInitializationException:42 - failed to lazily initialize a collection of role: com.pb.prism.model.db.ScenarioTblv.tblvScenarioCategory4List, no session or session was closed
      org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.pb.prism.model.db.ScenarioTblv.tblvScenarioCategory4List, no session or session was closed
          at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
          at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
          at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
          at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248)
          at com.pb.prism.util.AsyncServiceImpl.summaryPertSim_env(AsyncServiceImpl.java:446)
          at com.pb.prism.util.AsyncServiceImpl.batchUpdateSummaryPertSim(AsyncServiceImpl.java:41)
          at com.pb.prism.util.AsyncServiceImpl.startSlowProcess(AsyncServiceImpl.java:34)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.lang.reflect.Method.invoke(Unknown Source)
          at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
          at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:80)
          at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
          at java.util.concurrent.FutureTask.run(Unknown Source)
          at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
          at java.lang.Thread.run(Unknown Source)
  </code></pre>
  
  <p>Web.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"&gt;
  
  
     &lt;context-param&gt;
        &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;
     &lt;/context-param&gt;
     &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;
     &lt;/listener&gt;
     &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
     &lt;/listener&gt;
     &lt;listener&gt;
        &lt;listener-class&gt;com.pb.prism.listener.MTAServletContextListener&lt;/listener-class&gt;
     &lt;/listener&gt;
     &lt;context-param&gt;
        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;/WEB-INF/spring/web-application-context.xml&lt;/param-value&gt;
     &lt;/context-param&gt;
     &lt;filter&gt;
        &lt;filter-name&gt;openEntityManagerInViewFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter&lt;/filter-class&gt;
     &lt;/filter&gt;
     &lt;filter-mapping&gt;
        &lt;filter-name&gt;openEntityManagerInViewFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
     &lt;/filter-mapping&gt;
     &lt;!-- Enables Spring Security --&gt;
     &lt;filter&gt;
        &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
     &lt;/filter&gt;
     &lt;filter-mapping&gt;
        &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
     &lt;/filter-mapping&gt;
     &lt;filter&gt;
        &lt;filter-name&gt;encoding-filter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;
        &lt;init-param&gt;
           &lt;param-name&gt;encoding&lt;/param-name&gt;
           &lt;param-value&gt;UTF-8&lt;/param-value&gt;
        &lt;/init-param&gt;
     &lt;/filter&gt;
     &lt;filter-mapping&gt;
        &lt;filter-name&gt;encoding-filter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
     &lt;/filter-mapping&gt;
     &lt;filter&gt;
        &lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.tuckey.web.filters.urlrewrite.UrlRewriteFilter&lt;/filter-class&gt;
     &lt;/filter&gt;
     &lt;filter-mapping&gt;
        &lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
     &lt;/filter-mapping&gt;
     &lt;!-- Handles all requests into the application --&gt;
     &lt;filter&gt;
        &lt;filter-name&gt;OpenSessionInViewFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt;
     &lt;/filter&gt;
     &lt;filter-mapping&gt;
        &lt;filter-name&gt;OpenSessionInViewFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
     &lt;/filter-mapping&gt;
     &lt;servlet&gt;
        &lt;servlet-name&gt;Spring MVC Dispatcher Servlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
        &lt;init-param&gt;
           &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
           &lt;param-value /&gt;
        &lt;/init-param&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
     &lt;/servlet&gt;
     &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;Spring MVC Dispatcher Servlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/app/*&lt;/url-pattern&gt;
     &lt;/servlet-mapping&gt;
  &lt;/web-app&gt;
  </code></pre>
  
  <p>web-appliation-context.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:task="http://www.springframework.org/schema/task"
      xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd 
                           http://www.springframework.org/schema/task
                           http://www.springframework.org/schema/task/spring-task-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd"&gt;
  
      &lt;context:component-scan base-package="com.pb.prism" /&gt;
  
      &lt;!-- Imports the configurations of the different infrastructure systems of the application --&gt;
      &lt;import resource="data-access-context.xml" /&gt;
      &lt;import resource="security-context.xml" /&gt;
      &lt;import resource="webmvc-context.xml" /&gt;
  
      &lt;bean id="applicationContextProvider" class="com.pb.prism.context.ApplicationContextProvider"&gt;&lt;/bean&gt;
  
      &lt;!-- Configure the multipart resolver --&gt;
      &lt;bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt;
          &lt;!-- one of the properties available; the maximum file size in bytes --&gt;
          &lt;property name="maxUploadSize" value="2000000"/&gt;
      &lt;/bean&gt;
  
  
          &lt;task:annotation-driven executor="myExecutor" /&gt;    
          &lt;task:executor id="myExecutor" pool-size="5"/&gt;
  &lt;/beans&gt;
  </code></pre>