Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Вопрос про многопоточность и EntityManager

Автор вопроса: AlanObjectОтветов: 1

Я разрабатываю свое веб-приложение, используя реализацию JPA 2.0 EclipseLink 2.2.0. Наконец-то мне удалось запустить многопоточный код, и я получил это исключение:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

Объекты, которые имеют все вызовы javax.persistence в моем приложении, определяются как область приложения, например:

@Model
@ApplicationScoped
public class LocationControl implements Serializable {

    @PersistenceContext private EntityManager   em;
    @Resource           private UserTransaction utx;

    // etc

И, конечно же, все управляемые компоненты (обычно RequestScoped или ConversationScoped), которые хотят получить доступ к базе данных, делают это следующим образом:

@Inject private LocationControl lc;

Итак, мой вопрос заключается в следующем: получил ли я это исключение с помощью @ApplicationScoped DAO? Я думал, что так будет более эффективно, поскольку контейнеру не нужно будет постоянно воссоздавать этот объект при каждом запросе, если у него нет области действия, а у DAO нет собственного состояния. Однако если объекты EntityManager и UserTransaction должны быть отдельными экземплярами для каждого пользователя, это будет проблемой.

В качестве альтернативы я мог бы использовать синхронизированные методы DAO, но я думаю, что это приведет к блокировке потоков в контейнере (GlassFish).

Любые советы приветствуются.

  • Я не занимаюсь CDI, но этот LocationControl обычно должен был быть @Stateless EJB и должен быть внедрен @EJB. Я не знаю, что означает @Model, но в бизнес-классе это плохо пахнет. BalusC 30.08.2011

cdiglassfishjsf-2glassfish-3

Ответы

Ответ 1 · рейтинг 1 · Kris

Аннотация @Model изначально была создана для аннотирования bean-компонентов с областью действия запроса, вот как она определена:

@Named

@RequestScoped

@Stereotype

@Target({TYPE, METHOD, FIELD})

@Retention(RUNTIME)

public @interface Model {}

Конечно, вы можете переопределить "@RequestScoped" другой аннотацией, но "@ApplicationScoped" - это не лучший выбор, поскольку все в приложении изменят состояние одного и того же внедренного EntityManager. Я думаю, что в большинстве случаев было бы лучше оставить его @RequestScoped, иногда, например, для bean-компонента данных входа/выхода может быть вариант "@SessionScoped", но я не вижу сценария для дао "@ApplicationScoped".

Если вы вообще не хотите использовать @Model и используете полный контейнер Java EE, то EJB без сохранения состояния, как сказал BalusC, был бы отличным вариантом и для Dao.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы