【问题标题】:Why is Spring Data JPA Creating new EntityManager for shared EntityManager invocation?为什么 Spring Data JPA 为共享的 EntityManager 调用创建新的 EntityManager?
【发布时间】:2019-01-18 04:34:39
【问题描述】:

我有一个使用 spring boot + spring data JPA 的示例项目。在日志中,我观察到 EntityManager 在我进行第一次休息之前被创建了几次。请澄清为什么会发生这种情况。非常感谢。

Initialized JPA EntityManagerFactory for persistence unit 'ENTITY_MGR'
SpringBoot --> 10:05:40 8766 DEBUG org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler [main] - Creating new EntityManager for shared EntityManager invocation
SpringBoot --> 10:05:41 8963 DEBUG org.hibernate.stat.internal.StatisticsInitiator [main] - Statistics initialized [enabled=true]
SpringBoot --> 10:05:41 8977 TRACE org.hibernate.internal.SessionImpl [main] - Opened Session [f35fe4ac-8ce1-46b8-90dc-e456c07015c9] at timestamp: 15339099411
SpringBoot --> 10:05:41 8980 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils [main] - Closing JPA EntityManager
SpringBoot --> 10:05:41 8982 TRACE org.hibernate.internal.SessionImpl [main] - Closing session [f35fe4ac-8ce1-46b8-90dc-e456c07015c9]
SpringBoot --> 10:05:41 8982 INFO  org.hibernate.engine.internal.StatisticalLoggingSessionEventListener [main] - 
SpringBoot --> 10:05:41 8983 TRACE org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl [main] - Releasing JDBC resources
SpringBoot --> 10:05:41 8983 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Closing logical connection
SpringBoot --> 10:05:41 8983 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Logical connection closed
SpringBoot --> 10:05:41 8985 DEBUG org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler [main] - Creating new EntityManager for shared EntityManager invocation
SpringBoot --> 10:05:41 8986 TRACE org.hibernate.internal.SessionImpl [main] - Opened Session [26018255-8491-4014-98ad-fbce0d3b5109] at timestamp: 15339099412
SpringBoot --> 10:05:41 8986 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils [main] - Closing JPA EntityManager
SpringBoot --> 10:05:41 8986 TRACE org.hibernate.internal.SessionImpl [main] - Closing session [26018255-8491-4014-98ad-fbce0d3b5109]
SpringBoot --> 10:05:41 8986 INFO  org.hibernate.engine.internal.StatisticalLoggingSessionEventListener [main] - 
SpringBoot --> 10:05:41 8986 TRACE org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl [main] - Releasing JDBC resources
SpringBoot --> 10:05:41 8986 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Closing logical connection
SpringBoot --> 10:05:41 8986 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Logical connection closed
SpringBoot --> 10:05:41 9069 DEBUG org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler [main] - Creating new EntityManager for shared EntityManager invocation
SpringBoot --> 10:05:41 9069 TRACE org.hibernate.internal.SessionImpl [main] - Opened Session [4d3e7b5f-46fe-436f-9526-7ba62e332846] at timestamp: 15339099412
SpringBoot --> 10:05:41 9069 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils [main] - Closing JPA EntityManager
SpringBoot --> 10:05:41 9069 TRACE org.hibernate.internal.SessionImpl [main] - Closing session [4d3e7b5f-46fe-436f-9526-7ba62e332846]
SpringBoot --> 10:05:41 9069 INFO  org.hibernate.engine.internal.StatisticalLoggingSessionEventListener [main] - 
SpringBoot --> 10:05:41 9070 TRACE org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl [main] - Releasing JDBC resources
SpringBoot --> 10:05:41 9070 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Closing logical connection
SpringBoot --> 10:05:41 9070 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Logical connection closed
SpringBoot --> 10:05:41 9248 DEBUG org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler [main] - Creating new EntityManager for shared EntityManager invocation
SpringBoot --> 10:05:41 9248 TRACE org.hibernate.internal.SessionImpl [main] - Opened Session [1b5f5936-fa7f-42cd-831c-78570ace0f58] at timestamp: 15339099414
SpringBoot --> 10:05:41 9248 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils [main] - Closing JPA EntityManager
SpringBoot --> 10:05:41 9248 TRACE org.hibernate.internal.SessionImpl [main] - Closing session [1b5f5936-fa7f-42cd-831c-78570ace0f58]
SpringBoot --> 10:05:41 9249 INFO  org.hibernate.engine.internal.StatisticalLoggingSessionEventListener [main] - 
SpringBoot --> 10:05:41 9249 TRACE org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl [main] - Releasing JDBC resources
SpringBoot --> 10:05:41 9249 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Closing logical connection
SpringBoot --> 10:05:41 9249 TRACE org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl [main] - Logical connection closed

【问题讨论】:

  • 我有 70 条这样的行......永远得不到答案

标签: spring-boot


【解决方案1】:

我想知道同样的事情,这就是我发现的。

在 Spring 的许多情况下,它被用作EntityManager 字段的代理。我想这样做的原因是,与EntityManager 接口的实际实现相比,代理被认为是线程安全的,后者不是线程安全的。。 p>

例如CrudRepository 接口的默认实现-> SimpleJpaRepository 具有EntityManager 类型的字段。在大多数情况下,我们只想扩展CrudRepository 接口并将其作为单例bean 注入某处。由于它是单例,EntityManager 必须是线程安全的,因为可以从多个线程调用存储库。

SharedEntityManagerCreator 类的文档中,我们可以看到这个代理是如何工作的。

共享的 EntityManager 的行为就像从 JPA 规范定义的应用服务器的 JNDI 环境。 它将所有调用委托给当前事务性 EntityManager,如果有的话; 否则它将回退到每个操作新创建的 EntityManager。

这意味着如果创建了 EntityManager (Session),代理将使用它,如果没有,它将根据需要为您创建一个新的 EntityManager (Session)。

当我们启动 Spring Boot 应用程序时,Spring 会调用 一些 EntityManagers 但这些 EntityManagers 是代理,因为我们没有创建真正的 EntityManager (Session),所以它创建了一个为我们服务并记录您要求的这些消息。

因此,在您的情况下,创建这些共享的 EntityManagers 可能是因为您在项目中定义了 Repository 接口,并且在初始化期间在这些存储库中调用了 EntityManager(代理)。

【讨论】:

    猜你喜欢
    • 2018-09-30
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 2020-11-26
    • 2017-08-15
    • 1970-01-01
    相关资源
    最近更新 更多