Подтвердить что ты не робот

Инъекция EntityManager Vs. EntityManagerFactory

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

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

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

Аргумент для инъекции EFM заключается в том, что его хорошей практикой во всем его всегда хорошо иметь дескриптор для factory.

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

4b9b3361

Ответ 1

Преимущества и недостатки инъекции EntityManagerFactory vs EntityManager описаны в Spring docs здесь, я не уверен, что если я может улучшить это.

Сказав, что в вашем вопросе есть некоторые моменты, которые нужно прояснить.

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

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

Аргумент для инъекции ЭМП заключается в том, что его хорошая практика над всеми его всегда хорошо иметь ручку для factory.

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

Ответ 2

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

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

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

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

Ответ 3

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

  • DAO, если вводится Spring, , является singleton по умолчанию. Вы должны явно задает область действия прототипу каждый раз создавать новый экземпляр.

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

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

Последующее наблюдение:

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

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

Если вы используете PersistenceContextType.EXTENDED, имейте в виду, что вы должны, если я правильно понимаю, вручную закрыть транзакцию. Подробнее см. этот.

Другое наблюдение:

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

Ответ 4

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