title: Spring Boot closes hibernate session on shutdown - before @Async methods are finished
body: <p>I have a problem with a spring boot application that closes the EntityManager/session on shutdown before <code>@Async</code> tasks (that use the EntityManager) are finished.</p>
  
  <p>There are 2 classes relevant for this problem:</p>
  
  <p><strong>Scheduler</strong></p>
  
  <p>The scheduled method reserves a limited number of jobs and calls an <code>@Async</code> method on <code>XYJobProcessor</code> that does the actual work. </p>
  
  <pre><code>@Component
  public class XYJobProcessingTimer {
  
      private final XYJobService      xyJobService;
      private final XYJobProcessor    xyJobProcessor;
  
      //constructor skipped
  
      @Scheduled(initialDelayString = "${initial_delay}", fixedDelayString = "${delay}")
      public void performXYJobProcessing() {
          final String ticket = UUID.randomUUID().toString();
          final int reservedJobs = xyJobService.findAndReserveReadyXYJobs(ticket);
  
          if (reservedJobs &gt; 0) {
              final Collection&lt;XYJob&gt; xyJobs = xyJobService.readReservedJobs(ticket);
              xyJobProcessor.process(xyJobs);
          }
      }
  
  }
  </code></pre>
  
  <p><strong>Async Processor</strong></p>
  
  <p>The @Async annotated method calls the service that accesses the EntityManager.</p>
  
  <pre><code>@Service
  public class XYJobProcessor {
  
      private final XYJobService  xyJobService;
  
      // constructor skipped
  
      @Async("xyJobProcessorExecutor")
      public void process(final Collection&lt;XYJob&gt; jobs) {
          // This service uses the EntityManager and takes some time depending o job count.
          xyJobService.createXYJobsAndDelete(jobs);
      }
  
  }
  </code></pre>
  
  <p><strong>Configuration</strong></p>
  
  <p>The configuration of the <code>Executor</code> that runs the <code>@Async</code> tasks. The created Threads are non-daemon.</p>
  
  <pre><code>@Configuration
  public class AsyncExecutorConfiguration {
  
      @Bean(name = "xyJobProcessorExecutor")
      public Executor xyJobProcessorExecutor() {
          final SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
          executor.setConcurrencyLimit(10);
          executor.setThreadNamePrefix("Hasselhoff-");
          return executor;
      }
  
  }
  </code></pre>
  
  <p><strong>The Problem</strong></p>
  
  <p>When I shut down the application, spring closes the EntityManager Session immediately - before all <code>@Async</code> tasks have finished. This leads to the following Exception:</p>
  
  <pre><code>2017-08-31 16:10:54.212 ERROR 12663 --- [Hasselhoff-12] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected error occurred invoking async method 'public void de.xy.services.XYJobProcessor.process(java.util.Collection)'.org.springframework.orm.jpa.JpaSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
          at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
          at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
          at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
          at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
          at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
          at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
          at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
          at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
          at de.xy.services.XYJobService$$EnhancerBySpringCGLIB$$6b9cb1ae.createXYJobsAndDelete(&lt;generated&gt;)
          at de.xy.services.XYJobProcessor.process(XYJobProcessor.java:24)
          at de.xy.services.XYJobProcessor$$FastClassBySpringCGLIB$$ccc40c8f.invoke(&lt;generated&gt;)
          at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
          at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
          at java.util.concurrent.FutureTask.run(FutureTask.java:266)
          at org.springframework.core.task.SimpleAsyncTaskExecutor$ConcurrencyThrottlingRunnable.run(SimpleAsyncTaskExecutor.java:268)
          at java.lang.Thread.run(Thread.java:748)
  Caused by: org.hibernate.SessionException: Session is closed!
          at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:132)
          at org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:2088)
          at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:340)
          at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
          at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
          at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
          at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
          at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
          at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
          at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
          at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
          at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
          at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
          at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
          at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
          ... 17 common frames omitted
  </code></pre>
  
  <p>Is there a way to make Spring wait for <code>@Async</code> executions to finish before it closes the EntityManager? Or is this a bug?</p>