Вопрос о многопоточности и EntityManager - PullRequest
0 голосов
/ 30 августа 2011

Я разрабатывал свое веб-приложение с использованием реализации 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

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

@Inject private LocationControl lc;

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

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

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

1 Ответ

1 голос
/ 31 августа 2011

@ Аннотация модели была изначально создана для аннотирования запросов в рамках компонентов, вот как это определено:

@Named

@RequestScoped

@Stereotype

@Target({TYPE, METHOD, FIELD})

@Retention(RUNTIME)

public @interface Model {}

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

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

...