EntityManager был разработан, чтобы быть весьма кратковременным. Это технически возможно, чтобы держать его открытым в течение долгого времени, но рано или поздно вы столкнетесь следующие вопросы:
Как писал EnityManager
продолжает загружаться объекты и в самом деле он держит их, используя слабые ссылки (в по крайней мере, с Hibernate, но я не уверен, что это требуется спецификациями JPA). Поэтому они должны быть освобождены до того, как у JVM закончится память. К сожалению, я видел, что сохранение большого количества объектов влияет на производительность EM много (отрицательно, конечно), когда число растет.
Открытый EM может использовать соединение с базой данных, например. когда в памяти есть ленивые объекты.
EM по определению не является потокобезопасным, поэтому в веб-приложениях (например) повторное использование/совместное использование одного экземпляра совершенно неприемлемо.
Вероятно, самая большая проблема в том, что, когда есть какие-либо ошибки происходит в EM (например, на совершение сделки в связи с нарушением ограничений БД), JPA требует, чтобы EM должна быть закрыта как можно скорее и отбрасывают. Это приведет к тому, что все ваши объекты, находящиеся в памяти, будут отсоединены, что означает, что прикосновение к любым лениво загруженным коллекциям/ссылкам не удастся. Обходной путь для этого - перезагрузка всех объектов, но в больших приложениях это сложно, когда они разбросаны по всем слоям приложений. Решением этого является начало работы с отдельными объектами и использование EntityManager.merge()
. Но для этого обычно требуется изменение модели программирования, и, в частности, это противоречит принципу «всегда открытый» сущ. Вы должны использовать только один подход и придерживаться его.
Так вообще лучше держать EntityManager
недолговечны, это действительно упрощает много вещей.
# 1 верен для EclipseLink и может быть сконфигурирован с использованием ReferenceMode http://www.eclipse.org/eclipselink/api/2.3/org/eclipse/persistence/config/ReferenceMode.html – Chris
Я пропустил читать # 4 - это не относится к EclipseLink, что позволяет запускать ленивые отношения, пока контекст все еще доступен. Это будет недоступно только в том случае, если объект сериализуется или завод закрыт. – Chris