2014-01-31 2 views
3

Прошло несколько часов, над которыми я работаю, но до сих пор я не понял, как правильно использовать JPA с JSF.JPA и JSF: правильный способ инъекции EntityManager

У меня есть обработанный сеансом управляемый bean-компонент, который может делать много вещей, и один из них сохраняет некоторые объекты сущности. Вначале я создал метод-производитель, который запросит область действия, которая построит объекты EntityManager. В любом случае, прочитайте здесь, что инъекция запрошенного облачного объекта в сессионные области завершается переносом этого экземпляра в объект экземпляра. Готово. Но когда я пытаюсь использовать этот EM, я получил исключение для транзакции. Продолжайте читать в Интернете, кто-то говорит, что я должен ввести EM непосредственно в мои управляемые компоненты, используя аннотацию PersistenceContext. Во всяком случае, я думал, что имеет смысл использовать аннотацию persistenceUnit и создавать мои em внутри моих методов там, где они мне нужны. Инъекция работает, но я все еще получаю исключение в транзакции, когда пытаюсь что-то упорствовать!

Итак, здесь я спрашиваю: как правильно это сделать?

Редактировать: Я использую Jboss eap 6.2, используя настройки по умолчанию. Я развертываю свой источник данных с помощью XML-файла внутри WEB-INF, поэтому я использую JTA.

+0

Какова ваша среда выполнения? это важно, если вы используете только контейнер сервлетов или полномасштабный Java EE-сервер. – Yuri

+0

Добавляя к тому, что говорит @Yuri, [эта глава урока] (http://docs.oracle.com/javaee/6/tutorial/doc/bncih.html) объясняет, почему важно знать, используете ли вы JavaEE. – mabi

ответ

7

Я идиот. Я уже столкнулся с этой проблемой в прошлом, но я забыл.

Для всех, кто здесь работает с той же проблемой, является решение. Контейнерные управляемые транзакции работают только в том случае, если контейнер является EJB. Он НЕ работает, если контейнер JSF! Не имеет значения, как вы вводите менеджеров сущностей, успешные инъекции, но созданный объект не будет работать.

Способ решения проблемы, создает объект DAO EJB, который имеет дело с базой данных для вас. Что-то вроде

@Named 
@Stateless 
public class MyDAO { 

@PersistenceContext(unitName = "SRA") 
private EntityManager em; 

public void save(Object o) { 
    em.persist(o); 
    em.flush(); 
} 

}

, а затем инъекционные эти объекты внутри управляемого компонента, как это:

@ManagedBean 
@SessionScoped 
public class MyManagedBean { 
@EJB 
private MyDAO dao; 

public void action() { 
.... 
    dao.save(o); 
} 

}

инъекций непосредственно в EntityManager в Managed Bean даст вам Требуемое транзакционное исключение.

Я все еще не уверен в том, что вы впрыскиваете что-то подобное в более широкий круг фасоли. Я расскажу об этом позже.

+1

Для JSF 2.0+ я бы предложил не смешивать-использовать '@ Named' и' @ ManagedBean' - и придерживаться '@ Named'.Также я бы посоветовал придерживаться CDI-областей, а не версий JSF (внимательно изучите полное название пакета). – YoYo

2

«кто-то говорит, что я должен вводить EM непосредственно в мои управляемые компоненты, используя аннотацию PersistenceContext».

Если вы посмотрите на Java EE tutorial, что это именно то, что они делают

@Singleton 
public class MyUserDatabaseEntityManager { 
    // declare a producer field 
    @Produces 
    @UserDatabase 
    @PersistenceContext 
    private EntityManager em; 
} 

@ConversationScoped 
@Stateful 
public class RequestBean { 

    @Inject 
    @UserDatabase 
    EntityManager em; 

Это не может полностью ответить на ваш вопрос, но надеюсь, что это помогает.

Смежные вопросы