Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PersistenceContext lifecycle in Spring Boot

I'm trying to undestand, how the Persistence Context in Spring Boot application works. I use Spring Data, Hibernate and Hikari.

I can't find out, when the PersistenceContext is created and when it is closed. According to several articles, for example this one https://www.baeldung.com/jpa-hibernate-persistence-context or this one https://dzone.com/articles/how-does-spring-transactional the PersistenceContext lifecycle is the same as the EntityManager lifecycle. So I was wondering, when the EntityManager is actually created and more important when it is closed and most important if it is closed at the end of the transaction. According to what I found, the enum PersistenceContextType.java decides what PersistenceContext will I have. The PersistenceContextType.TRANSACTION should be default, should cause that the SharedEntityManagerInvocationHandler is used as the implementation of the EntityManager and should be closed at the end of the transaction, while PersistenceContextType.EXTENDED should outlive the transaction and should cause that the ExtendedEntityManagerInvocationHandler is being used. So I attempted to prove it by debugging and I found following.

  1. PersistenceContextType.EXTENDED is not being evaluated anywhere. There is some usage in PersistenceAnnotationBeanPostProcessor.java, but the breakpoint never stopped there in my integration tests.

  2. Sometimes SharedEntityManagerInvocationHandler#invoke and sometimes ExtendedEntityManagerInvocationHandler#invoke is being invoked, which doesn't tell me what kind of EntityManager does it use.

  3. In some occasions I even found SharedEntityManagerInvocationHandler wrapping ExtendedEntityManagerInvocationHandler.

The question is - how is it determined, if the PersistenceContext is closed at the end of transaction or not?

like image 886
Michal Krasny Avatar asked Dec 07 '25 03:12

Michal Krasny


1 Answers

PersistenceContextType.EXTENDED is not being evaluated anywhere. There is some usage in PersistenceAnnotationBeanPostProcessor.java, but the breakpoint never stopped there in my integration tests.

You will hit the breakpoint when you have the following field declaration in any of your beans:

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;

The question is - how is it determined, if the PersistenceContext is closed at the end of transaction or not?

Interesting question. If you dig through the Spring code a little, you will note that SharedEntityManagerInvocationHandler calls EntityManagerFactoryUtils.doGetTransactionalEntityManager(). The method registers a transaction synchronization for the returned EntityManager instance:

TransactionSynchronizationManager.registerSynchronization(
                                new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, false));

That synchronization is what closes the EntityManager after the transaction:

protected void releaseResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey) {
            closeEntityManager(resourceHolder.getEntityManager());
        }

You'll also note that ExtendedEntityManagerInvocationHandler does no such thing.

like image 103
crizzis Avatar answered Dec 08 '25 17:12

crizzis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!