I\'m using Spring framework.
The structure of my project is Controller ➡️ Service ➡️ Logic.
I added @Transactional
in Logic cla
I think this is a bug.
TransactionSynchronizationManager.bindResource((Object key, Object value)
will be called, and a new EntityManager will be bound to current thread.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
.EntityManager.flush()
. JdbcResourceLocalTransactionCoordinatorImpl.isJoined()
will be called to check.TransactionSynchronizationManager.bindResource((Object key, Object value)
will be called, and a new EntityManager will be bound to current thread.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.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?
I found the solution.
Just add entityManager.joinTransaction()
;.