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 callEntityManager.joinTransaction()
. This method will callJdbcResourceLocalTransactionCoordinatorImpl.getTransactionDriverControl()
to initializeTransactionDriverControlImpl 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, butEntityManager.joinTransaction()
will not be called. SoTransactionDriverControlImpl physicalTransactionDelegate
will not be initialized. - When we call
EntityManager.flush()
. SinceTransactionDriverControlImpl 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.