Самый простой способ получить ViewScope и избежать исключения LazyInitializationException в стеке JBoss AS7 (JSF2, CDI, JPA2, Seam?)

Я пытаюсь настроить стек веб-приложений на основе JBoss AS7 для небольших исследовательских прототипов и студенческих проектов, который отвечает следующим требованиям:

  1. Я хочу использовать связанные с AJAX области видимости, такие как ViewScope, или, возможно, (View)AccessScope, как в MyFaces Orchestra, для моих управляемых компонентов в сочетании с компонентами PrimeFaces.

  2. Сохранение на основе JPA должно быть довольно простым, без необходимости иметь дело с шаблоном OpenSessionInView и т. Д. Основная проблема, с которой я сталкиваюсь с JPA2, — это ужасное LazyInitializationException, особенно в вызовах AJAX. Мне не требуется ручное управление разговорами.

  3. Я хочу использовать как можно меньше зависимостей, поэтому в основном полагаюсь на то, что поставляется с JBoss AS7.

Прямо сейчас я создал проект со следующими (в основном предоставленными) зависимостями Maven:

  • КДИ
  • спящий режим-2.0-API
  • jboss-ejb-api_3.1_spec
  • jboss-jsf-api_2.1_spec
  • jboss-аннотации-api_1.1_spec
  • PrimeFaces 3

Это выглядит довольно тонким до сих пор. Чего не хватает, так это поддержки дополнительных областей, специфичных для JSF, и того, что я всегда получаю исключение LazyInitializationException при переборе коллекций на странице JSF. Прямо сейчас мои сервисные классы для постоянства выглядят так:

import javax.ejb.Stateful;
import javax.enterprise.context.RequestScoped;

@Stateful @RequestScoped
public class TestEntityService implements Serializable {
    @PersistenceContext(type=PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    // ... some methods working with the entityManager ...
}

И мой bean-компонент ResourceFactory:

public class ResourceFactory {
    @Produces @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
}

Я безуспешно пробовал комбинации с @Named вместо @Stateful или @SessionScoped вместо @RequestScoped. Тем не менее, я обнаружил, что добавление модулей Seam 3 Persistence, Solder & Faces, по-видимому, решает большинство моих проблем, но это добавляет массу новых зависимостей в мой проект (например, безопасность швов, красивые лица, слюни, время joda и другие зависимости). ).

Мои вопросы:

  1. Будут ли EJB чем-то полезны по сравнению с другими? LazyInitializationException? Или я на самом деле уже использую здесь EJB из-за аннотации @Stateful? Я взял это из примера приложения jboss-as, но меня совершенно смущают различия между всеми этими аннотациями @ManagedBean, @Named, @Stateful, @LocalBean... все, что я знаю, это то, что мне как-то нужно привязать продолжительность жизни моих менеджеров объектов к область действия bean-компонента службы.

  2. Кто-нибудь знает другие простые способы обойти эту проблему? Использование извлечения EAGER не вариант, так как это работает только в том случае, если на объект не более одной коллекции...

  3. Я только что прочитал об Apache CODI, который, похоже, является преемником CDI MyFaces Orchestra. Это лучшая альтернатива Seam Faces? Насколько я вижу, он предлагает ViewScope и ViewAccessScope, но ничего в отношении управления транзакциями.

Было бы здорово, если бы кто-то с большим опытом в этой области мог пролить свет на это - в настоящее время я немного сбит с толку, потому что существует так много библиотек, решающих аналогичные проблемы, хотя, по-видимому, они несовместимы друг с другом (см. например здесь). Спасибо!


person tlind    schedule 30.05.2012    source источник
comment
Использование извлечения EAGER не вариант, так как это работает только в том случае, если для каждой сущности имеется не более одной коллекции - это может сработать, если вы используете Set вместо List для коллекции. IIRC это как-то связано с порядком элементов. Но попробовать стоит ;-)   -  person Dominik Sandjaja    schedule 10.07.2012


Ответы (2)


Ты прав. Все это довольно запутанно. Эта путаница возникает из-за того, что JSF2 и CDI предоставляют одну и ту же функцию. Поскольку эти две спецификации должны работать без друг друга, они имеют аналогичные аннотации для экспозиции Scope и EL. Этот сообщение в блоге подробно описывает эти запутанные области и как сделать правильный выбор. Короче говоря, при использовании CDI с JSF всегда используйте аннотации CDI или аннотации, которыми CDI будет управлять через расширение (как javax.faces.ViewScoped, если в вашем проекте есть Seam Faces или CODI)

Чтобы ответить на ваши вопросы

  1. Вы уже используете EJB с аннотацией @Stateful. EJB не поможет вам напрямую с LazyInitializationException, но они являются более естественным вариантом для работы с транзакциями и базой данных (вы не можете использовать аннотацию @PersistenceContext в bean-компоненте pojo CDI). По поводу запутанных аннотаций я уже ответил
  2. У меня есть хороший опыт работы с Seam Persistence. Это расширение CDI создает управляемый диспетчер сущностей, который живет в диалоге и позволяет использовать транзакцию вне EJB (если у вас нет контейнера Java EE). Использование этого диспетчера сущностей значительно снижает проблемы с ленивой лодкой. Его можно внедрить в EJB без сохранения состояния, который управляет вашим DAO благодаря магии CDI, которая позволяет внедрять Bean-компоненты различной области действия. При использовании в сочетании с Seam Faces вы получите поддержку JSF ViewScope для CDI и транзакции, привязанной к жизненному циклу JSF.
  3. У меня нет опыта работы с CODI, который, кажется, предоставляет полезные функции, такие как вложенный диалог.

В заключение, имейте в виду, что сейчас Seam и CODI находятся в процессе слияния в Apache Delta Spike, поэтому решение, которое вы собираетесь создать, должно быть переоценено в следующем месяце, чтобы включить Delta Spike в уравнение.

person Antoine Sabot-Durand    schedule 31.05.2012
comment
Спасибо за ответы! Я не знал об Apache Delta Spike и буду следить за ходом этого проекта инкубатора. - person tlind; 31.05.2012

Честно говоря, для CDI не существует универсального решения. Seam3 отлично работает, MyFaces CODI отлично работает, это действительно зависит от того, что вы хотите. Честно говоря, в вашей ситуации кажется, что проще всего будет создать собственное расширение ViewScoped для вашего проекта или взять необходимые части из Seam 3 или CODI.

person LightGuard    schedule 31.05.2012