#java #ejb-3.0 #java-ee-5
#java #ejb-3.0 #java-ee-5
Вопрос:
Существует ли контекст с областью запроса для сеансовых компонентов EJB3? Моей средой является Java-EE-5.
Этот пример
@Remote(SessionFacade.class) @Stateless
public class SessionFacadeBean implements SessionFacade {
@EJB
private Other bean;
public void myBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 1 ));
bean.otherBusinessMethod();
sysout(*myRequestScope*.get("demo"));
}
}
@Local(Other.class) @Stateless
public class OtherBean implements Other {
public void otherBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 2 ));
}
}
всегда следует выводить «2» при вызове SessionFacadeBean#myBusinessMethod() — независимо от параллельных вызовов.
Я не могу позволить себе роскошь использовать CDI. И это также должно работать независимо от распространения транзакции (поэтому JCA также не является вариантом).
Ответ №1:
EJB без состояния, как следует из их названия, не сохраняют состояние, поэтому понятия области запроса не существует. Существует область сеанса, которая ограничена текущим контекстом сеанса во время выполнения, где вы также не можете сохранять состояние, так что это исключает любой вариант сохранения состояния внутри компонента или в контейнере.
Возможно, вам повезет, если вы будете использовать ThreadLocal
переменные, но это, как следует из названия, ограничено текущим потоком выполнения. Судя по вашему опубликованному коду, это именно то, чего вы хотели бы. Проблема с этим подходом заключается в том, что,
Thread
объекты просто не уничтожаются после завершения выполнения метода EJB; они возвращаются в пул потоков контейнера. Следовательно, если вы прочитаете значение ThreadLocal в другом контексте выполнения, вы найдете значение предыдущего контекста выполнения, в котором использовался тот же поток. Другими словами, убедитесь, что ваше приложение всегда помещает значения в объект ThreadLocal перед их чтением.- Кроме того, освободите любые объекты ThreadLocal, как только они вам не понадобятся, иначе у вас возникнет утечка памяти.
Комментарии:
1. Отсутствие состояния здесь не проблема. Сервлеты также не имеют состояния. Если бы мой SLSF был веб-сервисом, я мог бы получить
WebServiceContext
введенный — который по преимуществу является областью запроса. Для меня все еще выглядит как пробел в спецификации.2. (Ранее у меня был комментарий относительно EJBContext.getContextData, но это не будет делать то, что вы хотите. Извините.)
3. Состояния без состояния сохраняют состояние! Состояние диалога, действительное во время вызова метода!
4. @justin.hughey Это для Java EE 5? Прочитайте вопрос.
5. Я сказал, что это было? Предоставляется ли это как «Ответ»? Хотя я не давал дополнительного контекста, это не было задумано как ответ. Поиск в Google этой проблемы в контексте, отличном от EE5, приводит вас сюда. Это было моим намерением помочь другим. Извините, если это неприемлемо.
Ответ №2:
Существует ли контекст с областью запроса для компонентов сеанса без состояния?
Короткий ответ — нет.
Длинный ответ таков: вам нужен некоторый контекст для обмена данными между вызовами ваших бизнес-методов. Это может быть проблемой дизайна. Requestscope — это концепция веб-уровня.
-
На веб-уровне запрос, страница, сеанс и область приложения реализованы в виде хэш-карты. Таким образом, вы могли бы передать ссылку на Hashmap в качестве контекста для совместного использования всех данных.
-
Другим подходом может быть использование синглтона (который должен быть общим для узлов, например, с использованием ehcache).
-
Перейдите на EJB 3.1 и используйте @Singleton
-
Рассмотрите возможность использования компонентов с сохранением состояния и поместите область вашего запроса в область сеанса beans, которая может быть удалена после выхода из области запроса.
Комментарии:
1. Сеансовый компонент с отслеживанием состояния (в смысле корзины покупок для перемещения) также не работает. Если я использую механизм @EJB-injection, экземпляр OtherBean не получит тот же экземпляр SFSB, что и экземпляр SessionFacaceBean