Это должно хорошо передать, ввел EntityManagers к классам помощника боба EJB, и используйте его?

У нас есть некоторый боб EJB не сохраняющий состояние JavaEE5, который передает введенный EntityManager его помощникам.

Действительно ли это безопасно? Это работало хорошо до сих пор, но я узнал некоторый документ Oracle, который указывает, что его реализация EntityManager ориентирована на многопотоковое исполнение. Теперь интересно, был ли причина, у нас не было проблем до сих пор, то, только потому, что реализация, которую мы использовали, оказалось, была ориентирована на многопотоковое исполнение (мы используем Oracle).

@Stateless
class SomeBean {
    @PersistenceContext
    private EntityManager em;

    private SomeHelper helper;

    @PostConstruct
    public void init(){
        helper = new SomeHelper(em);
    }

    @Override
    public void business(){
        helper.doSomethingWithEm();
    }

}

На самом деле это имеет смысл.. Если бы EntityManager небезопасен потоком, контейнер должен был бы сделать

inercept business()
this.em = newEntityManager();
business();

который не распространит к его классам помощника.

Если так, какова лучшая практика в этом своего рода ситуация? Передача EntityManagerFactory вместо EntityManager?

Править: Этот вопрос очень интересен поэтому, если Вы интересуетесь этим вопросом, Вы, вероятно, хотите проверить этого, также:

Спецификация Править: Подробнее. ejb3.0

4.7.11 Неповторно используемые Экземпляры контейнер должен гарантировать, что только один поток может выполнять экземпляр в любое время. Если клиентский запрос прибывает для экземпляра, в то время как экземпляр выполняет другой запрос, контейнер может бросить javax.ejb. ConcurrentAccessException второму клиенту [24]. Если клиентское EJB 2.1 представление используется, контейнер может бросить java.rmi. RemoteException к второму запросу, если клиент является удаленным клиентом или javax.ejb. EJBException, если клиент является локальным клиентом. [25] Примечание, что объект сессии предназначается для поддержки только единственного клиента. Поэтому это была бы ошибка приложения, если бы два клиента попытались вызвать тот же объект сессии. Одна импликация этого правила - то, что приложение не может сделать вызовы петлевой проверки к бобовому экземпляру сессии.

И,

4.3.2 Внедрение зависимости боб сессии может использовать механизмы внедрения зависимости для получения ссылок на ресурсы или другие объекты в его среде (см. Главу 16, “Среда Компонента уровня предприятия”). Если боб сессии использует внедрение зависимости, контейнер вводит эти ссылки после того, как бобовый экземпляр создается, и прежде чем любые бизнес-методы будут вызваны на бобовый экземпляр. Если зависимость от SessionContext объявляется, или если класс компонента реализует дополнительный интерфейс SessionBean (см. Раздел 4.3.5), SessionContext также введен в это время. Если внедрение зависимости перестало работать, бобовый экземпляр отбрасывается. Под EJB 3.0 API класс компонента может получить интерфейс SessionContext посредством внедрения зависимости, не имея необходимость реализовывать интерфейс SessionBean. В этом случае аннотация Ресурса (или resource-env-ref элемент дескриптора развертывания) используется для обозначения зависимости боба от SessionContext. См. Главу 16, “Среда Компонента уровня предприятия”.

6
задан Community 23 May 2017 в 12:19
поделиться

2 ответа

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

У меня также был вариант, когда менеджер сущностей не инжектировался (потому что EJB вообще его не использовал), поэтому хелпер должен был искать его с помощью InitialContext. В этом случае контекст персистентности все равно должен быть "импортирован" в родительский EJB с помощью @PersistenceContext:

@Stateless 
@PersistenceContext(name="OrderEM") 
public class MySessionBean implements MyInterface { 
  @Resource SessionContext ctx; 
  public void doSomething() { 
     EntityManager em = (EntityManager)ctx.lookup("OrderEM"); 
     ... 
  } 
}

Но на самом деле проще инжектировать его (даже если EJB его не использует), чем искать его, особенно для тестируемости.

Но чтобы вернуться к вашему основному вопросу, я думаю, что менеджер сущностей, который инжектируется или просматривается, является оберткой, которая переадресует к основному активному менеджеру сущностей, который привязан к транзакции.

Надеюсь, это поможет.

EDIT

Разделы § 3.3 и § 5.6 в спецификации немного освещают эту тему.

2
ответ дан 17 December 2019 в 07:03
поделиться

Я использовал вспомогательные методы и передавал туда EntityManager, и все в порядке.

Так что я бы рекомендовал либо передавать его в методы, когда это необходимо, либо сделать хелпер самим бобом, инжектировать его (используя @EJB) и инжектировать туда EntityManager.

2
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: