Affects: 5.0.7.RELEASE**

I have a question about why entityManager.flush() raises an exception when @Async is used.

This question is raised in Stack Overflow.

Comment From: sbrannen

Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.

Comment From: huashui

Thanks for replying. I think this is a bug.

  • With No @Async
  • When request comes, TransactionSynchronizationManager.bindResource((Object key, Object value) will be called, and a new EntityManager will be bound to current thread.
  • Then, EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) is called to get the bound EntityManager. Inside this method, it will call EntityManager.joinTransaction(). This method will call JdbcResourceLocalTransactionCoordinatorImpl.getTransactionDriverControl() to initialize TransactionDriverControlImpl physicalTransactionDelegate.
  • When we call EntityManager.flush(). JdbcResourceLocalTransactionCoordinatorImpl.isJoined()will be called to check.
  • With @Async
  • When request comes, TransactionSynchronizationManager.bindResource((Object key, Object value) will be called, and a new EntityManager will be bound to current thread.
  • If there is a @Async, a new thread will be created.
  • Then, EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) is called to get the bound EntityManager. But in this new thread, there is no bound EntityManager, so a new one will be created, but EntityManager.joinTransaction() will not be called. So TransactionDriverControlImpl physicalTransactionDelegate will not be initialized.
  • When we call EntityManager.flush(). Since TransactionDriverControlImpl physicalTransactionDelegate is null, an exception will be raised.

Why EntityManager.joinTransaction() is not called when a new EntityManager is created in a new thread?

Comment From: sbrannen

Can you please provide the stack trace for the exception that is raised in your @Async scenario?

Comment From: huashui

Thank you for your reply. This is the stack trace for the exception.

Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350) at com.sun.proxy.$Proxy150.flush(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305) at com.sun.proxy.$Proxy150.flush(Unknown Source) at jp.co.common.interceptor.FlushInterceptor.flush(FlushInterceptor.java:30) ... 89 more

Comment From: snicoll

I am afraid we'll need a sample to better understand how the thread is created and the transaction applied. You can share it by attaching a zip to this issue or pushing the code to a separate GitHub repository.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.