Внедрение EntityManager Vs.EntityManagerFactory - объект управления

StackOverflow https://stackoverflow.com/questions/1310087

Вопрос

Длинный вопрос, пожалуйста, выслушайте меня.

Мы используем Spring + JPA для веб-приложения.Моя команда обсуждает вопрос об инъекциях EntityManagerFactory в GenericDAO (DAO, основанный на дженериках чего-либо в строках, предоставляемых APPFUSE, мы не используем JpaDaosupport по какой-то причине) чрезмерное введение EntityManager.Мы используем "персистентность, управляемую приложением".

Аргументы против введения EntityManagerFactory заключается в том, что он слишком тяжелый и поэтому не требуется, EntityManager делает то, что нам нужно.Кроме того, поскольку Spring создаст новый экземпляр DAO для каждого веб-запроса (я сомневаюсь в этом), не возникнет никаких проблем с параллелизмом, как в том же EntityManager экземпляр является общим для двух потоков.

Аргумент в пользу внедрения EFM заключается в том, что это хорошая практика, и всегда полезно иметь доступ к фабрике.

Я не уверен, какой подход лучше, может кто-нибудь, пожалуйста, просветить меня?

Это было полезно?

Решение

Все плюсы и минусы внедрения EntityManagerFactory против EntityManager описаны в Spring docs здесь, Я не уверен, что смогу улучшить это.

Говоря это, в вашем вопросе есть некоторые моменты, которые следует прояснить.

...Spring создаст новый экземпляр DAO для каждого веб-запроса...

Это неверно.Если ваш DAO является Spring bean, то это синглтон, если только вы не настроите его иным образом с помощью scope атрибут в определении компонента.Создавать экземпляр DAO для каждого запроса было бы безумием.

Аргумент в пользу введения ЭДС заключается в том, что это хорошая практика во всех ее проявлениях всегда полезно иметь доступ к заводу.

На самом деле этот аргумент не выдерживает критики.Общая надлежащая практика гласит, что объект должен быть внедрен с минимальным количеством сотрудников, необходимых ему для выполнения своей работы.

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

Я записываю то, что мне наконец удалось собрать.Из раздела "Реализация DAO на основе простого JPA" в Весеннем Справочнике:

Хотя экземпляры EntityManagerFactory потокобезопасны, экземпляры EntityManager таковыми не являются.Внедренный JPA EntityManager ведет себя подобно EntityManager, извлеченному из среды JNDI сервера приложений, как определено спецификацией JPA.Он делегирует все вызовы текущему транзакционному EntityManager, если таковой имеется;в противном случае он возвращается к вновь созданному EntityManager для каждой операции, фактически делая его потокобезопасным при использовании.

Это означает, что в соответствии со спецификациями JPA экземпляры EntityManager не являются потокобезопасными, но если Spring обрабатывает их, они становятся потокобезопасными.

Если вы используете Spring, лучше ввести EntityManagers вместо EntityManagerFactory.

Я думаю, что это уже было хорошо рассмотрено, но просто для того, чтобы подчеркнуть несколько моментов.

  • ДАО, если оно введено Пружиной, является синглтоном по умолчанию.Вы должны явно установить область видимости в prototype чтобы каждый раз создавать новый экземпляр.

  • Менеджер сущностей, введенный с помощью @PersistenceContext является ли потокобезопасным.

Тем не менее, у меня действительно были некоторые проблемы с одноэлементным DAO в моем многопоточном приложении. В итоге я превратил DAO в экземпляр bean, и это решило проблему. Таким образом, хотя документация может говорить одно, вы, вероятно, захотите тщательно протестировать свое приложение.

Последующие меры:

Я думаю, что часть моей проблемы заключается в том, что я использую

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

Если вы используете PersistenceContextType.РАСШИРЕННЫЙ, имейте в виду, что вам придется, если я правильно понимаю, вручную закрыть транзакцию.Видишь это перейдите по ссылке для получения дополнительной информации.

Еще одно последующее мероприятие:

Использование экземпляра DAO - крайне плохая идея.Каждый экземпляр DAO будет иметь свой собственный кэш сохраняемости, и изменения в одном кэше не будут распознаны другими компонентами DAO.Извините за плохой совет.

Я обнаружил, что установка аннотации @Repository Spring в наших DAO и управление EntityManager с помощью Spring и внедрение аннотации @PersistenceContext — это наиболее удобный способ заставить все работать плавно.Вы получаете выгоду от потокобезопасности общего EntityManager и трансляции исключений.По умолчанию общий EntityManager будет управлять транзакциями, если вы, например, объедините несколько DAO из менеджера.В конце концов вы обнаружите, что ваши DAO станут анемичными.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top