2013-07-02 4 views
2

У меня есть этот вопрос, Keeping JPA EntityManager open?, но у меня все еще есть некоторые проблемы.Всегда открывать EntityManager

Это хорошая идея всегда открывать EnityManager во время применения? Использует ли он некоторые ресурсы, такие как подключение к базе данных? Сохраняет ли он сущности или освобождает их, если использует слабые ссылки? Я использую EclipseLink 2.x.

Благодаря

Zlaja

ответ

2

EntityManager был разработан, чтобы быть весьма кратковременным. Это технически возможно, чтобы держать его открытым в течение долгого времени, но рано или поздно вы столкнетесь следующие вопросы:

  1. Как писал EnityManagerпродолжает загружаться объекты и в самом деле он держит их, используя слабые ссылки (в по крайней мере, с Hibernate, но я не уверен, что это требуется спецификациями JPA). Поэтому они должны быть освобождены до того, как у JVM закончится память. К сожалению, я видел, что сохранение большого количества объектов влияет на производительность EM много (отрицательно, конечно), когда число растет.

  2. Открытый EM может использовать соединение с базой данных, например. когда в памяти есть ленивые объекты.

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

  4. Вероятно, самая большая проблема в том, что, когда есть какие-либо ошибки происходит в EM (например, на совершение сделки в связи с нарушением ограничений БД), JPA требует, чтобы EM должна быть закрыта как можно скорее и отбрасывают. Это приведет к тому, что все ваши объекты, находящиеся в памяти, будут отсоединены, что означает, что прикосновение к любым лениво загруженным коллекциям/ссылкам не удастся. Обходной путь для этого - перезагрузка всех объектов, но в больших приложениях это сложно, когда они разбросаны по всем слоям приложений. Решением этого является начало работы с отдельными объектами и использование EntityManager.merge(). Но для этого обычно требуется изменение модели программирования, и, в частности, это противоречит принципу «всегда открытый» сущ. Вы должны использовать только один подход и придерживаться его.

Так вообще лучше держать EntityManager недолговечны, это действительно упрощает много вещей.

+0

# 1 верен для EclipseLink и может быть сконфигурирован с использованием ReferenceMode http://www.eclipse.org/eclipselink/api/2.3/org/eclipse/persistence/config/ReferenceMode.html – Chris

+0

Я пропустил читать # 4 - это не относится к EclipseLink, что позволяет запускать ленивые отношения, пока контекст все еще доступен. Это будет недоступно только в том случае, если объект сериализуется или завод закрыт. – Chris