【问题标题】:PersistenceContext lifecycle in Spring BootSpring Boot 中的 PersistenceContext 生命周期
【发布时间】:2021-06-14 01:03:57
【问题描述】:

我试图理解 Spring Boot 应用程序中的持久性上下文是如何工作的。我使用 Spring Data、Hibernate 和 Hikari。

我不知道PersistenceContext 何时创建以及何时关闭。根据几篇文章,例如https://www.baeldung.com/jpa-hibernate-persistence-contexthttps://dzone.com/articles/how-does-spring-transactional 这一PersistenceContext 生命周期与EntityManager 生命周期相同。所以我想知道,当EntityManager 实际创建时,它关闭时更重要,最重要的是它在事务结束时关闭。根据我的发现,枚举PersistenceContextType.java 决定了我将拥有什么PersistenceContextPersistenceContextType.TRANSACTION 应该是默认的,应该导致 SharedEntityManagerInvocationHandler 被用作 EntityManager 的实现并且应该在事务结束时关闭,而 PersistenceContextType.EXTENDED 应该比事务更有效并且应该导致 @正在使用 987654333@。所以我尝试通过调试来证明它,我发现了以下内容。

  1. PersistenceContextType.EXTENDED 没有在任何地方进行评估。 PersistenceAnnotationBeanPostProcessor.java 有一些用法,但是在我的集成测试中断点从未停止过。

  2. 有时会调用SharedEntityManagerInvocationHandler#invoke,有时会调用ExtendedEntityManagerInvocationHandler#invoke,但这并不能告诉我它使用的是哪种EntityManager

  3. 在某些情况下,我什至发现SharedEntityManagerInvocationHandler 包装了ExtendedEntityManagerInvocationHandler

问题是 - 如何确定PersistenceContext 在交易结束时是否关闭?

【问题讨论】:

    标签: java spring-boot hibernate jpa hikaricp


    【解决方案1】:

    PersistenceContextType.EXTENDED 没有在任何地方进行评估。 PersistenceAnnotationBeanPostProcessor.java 有一些用法,但是在我的集成测试中断点从未停止过。

    当您的任何 bean 中有以下字段声明时,您将遇到断点:

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

    问题是——如何确定 PersistenceContext 是否在事务结束时关闭?

    有趣的问题。如果您仔细研究一下 Spring 代码,您会注意到 SharedEntityManagerInvocationHandler 调用了 EntityManagerFactoryUtils.doGetTransactionalEntityManager()。该方法为返回的EntityManager实例注册一个事务同步:

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

    该同步是在事务后关闭EntityManager

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

    您还会注意到,ExtendedEntityManagerInvocationHandler 并没有这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-10
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 2014-12-04
      • 1970-01-01
      • 2015-01-08
      相关资源
      最近更新 更多