Должен ли я закрывать() каждый EntityManager?

Я только что начал переносить свою внутреннюю структуру сохранения на JPA.

Учитывая, что структуры persistence скрывают много сантехники, я заинтересован в том, чтобы узнать, не закрывает ли EntityManager проблему с утечкой ресурса, или если структуры будут собирать и закрывать их для меня.

Я намерен во всех местах закрыть их, но есть ли у меня?

В настоящий момент, используя TopLink, просто потому, что он работает с NetBeans легко, но я рад исследовать других поставщиков JPA.

Ответ 1

Это зависит от того, как вы его получили.

Если вы создали его с помощью EntityManagerFactory, вам придется закрыть его независимо от того, какую структуру вы используете.

Если вы получили его с помощью инъекции зависимостей (например, с помощью аннотации EJB и @PersistenceContext), вы не должны закрывать его вручную (AFAIK вызывает RuntimeException).

Ответ 2

Вы должны.

Структуры не имеют представления о том, как вы собираетесь использовать EM, поэтому они не могут ее закрыть (за исключением, возможно, при завершении, что не гарантируется). Да, не закрывая их, это создаст утечку ресурсов.

Идея такая же, как "всегда закрыть java.sql.Connection" (несмотря на то, что некоторые источники данных имеют настройки для автоматического закрытия их бездействия) или "всегда закрывать сеанс Hibernate".

Кроме того, если вы планируете писать переносимый код, вы не должны полагаться на конкретного провайдера JPA, "умного" - другие могут не закрывать EM вовремя.

Ответ 3

Я получил EntityManager с помощью аннотации @PersistenceContext в моем репозитории. Я вижу, что после того, как соединительные пулы достигнут своего maxPoolSize, он не очищается.

Однако, если я создаю EntityManager с помощью EntityManagerFactory и вызываю entitymanager.close(), тогда соединения очищаются. Я использую c3p0 в качестве библиотеки подключения.