Почему spring data jpa создает новый entitymanager для общего вызова entitymanager?

У меня есть образец проекта с использованием 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 тезисов ... никогда не получаю ответа

robert trudel 23.09.2020 19:39
4
1
565
1

Ответы 1

Я задавался вопросом о том же самом, и вот что я нашел.

Во многих случаях в Spring используется прокси для полей EntityManager. Я предполагаю, что причина этого в том, что прокси называется потокобезопасный по сравнению с реальными реализациями интерфейса EntityManager, который не являются потокобезопасными.

Например, реализация интерфейса CrudRepository по умолчанию -> SimpleJpaRepository имеет поле типа EntityManager. И в большинстве случаев мы просто хотим расширить интерфейс CrudRepository и внедрить его куда-нибудь как одноэлементный компонент. Поскольку это синглтон, EntityManager должен быть потокобезопасный, потому что репозиторий может быть вызван из нескольких потоков.

В документации класса SharedEntityManagerCreator мы можем увидеть, как на самом деле работает этот прокси.

A shared EntityManager will behave just like an EntityManager fetched from an application server's JNDI environment, as defined by the JPA specification. It will delegate all calls to the current transactional EntityManager, if any; otherwise it will fall back to a newly created EntityManager per operation.

Это означает, что если существует EntityManager (Session), прокси будет использовать его, а если его нет, он по запросу создаст для вас новый EntityManager (Session).

Когда мы запускаем наше приложение Spring Boot, Spring вызывает некоторыеEntityManager, но эти EntityManager являются прокси, и поскольку у нас нет реального EntityManager (Session), созданного, он создает его для нас и регистрирует эти сообщения, которые вы запрашиваете.

Итак, в вашем случае эти общие EntityManager создаются, вероятно, потому, что вы определили интерфейсы Repository в своем проекте и во время инициализации в этих репозиториях есть вызовы EntityManager (прокси).

Другие вопросы по теме