JTA EntityManager без ръчни ангажименти

Опитвам се да преместя проекта си от Seam 3.

Сега съм заседнал на JTA транзакции след изключване на модула Seam Faces. Имаше интегрирано управление на транзакциите. Транзакциите бяха започнати и се ангажираха автоматично - без ръчно ангажиране.

Сега, когато се опитвам да изпълня EntityManager.persist() или EntityManager.merge(Object entity), получавам грешка:

JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)

Има ли някакъв начин да принудите JTA да стартира транзакция и да я извърши прозрачно?

Пс. Странно нещо - преди известно време търсих решение как да принудя ръчно извършване/връщане назад в Seam3.

Добре, ако поставя bean в състояние @Stateless - тогава той се държи както очаквах.

Но...

Не е ли - че ако сложа управляван от приложение EntityManager - тогава трябва да управлявам транзакцията самостоятелно (метод testApplicationJTA() в примера по-долу), но ако използвам управляван от контейнер EntityManager - тогава трябва да работи без управление на транзакция (метод testContainterJTA() )?

моят пример:

@Named
@SessionScoped
public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    @PersistenceContext
    private EntityManager           em;

    @PersistenceUnit
    private EntityManagerFactory    emf;

    @Resource
    private UserTransaction         utx;

    public void testContainerJTA() {
        TestEntity entity = em.find(TestEntity.class, 1L);
        entity.setName("dddddd");
        em.merge(entity);

    }

    public void testApplicationJTA() {
        EntityManager mgr = emf.createEntityManager();
        TestEntity entity = em.find(TestEntity.class, 1L);
        entity.setName("fffff");
        try {
            utx.begin();
            mgr.joinTransaction();
            mgr.merge(dict);
            utx.commit();
        } catch (Exception e) {
            utx.rollback();
        }

        mgr.close();

    }
}

В моя пример по-горе методът testContainerJTA() не работи. Защо?

Ако премахна @SessionScoped и сложа @Stateless, тогава метод testApplicationJTA() не работи, но testContainerJTA() работи. Защо?

Не трябва ли да работят и двете винаги - като управление на приложение и управление на контейнер?


person robson    schedule 20.04.2013    source източник
comment
Използвайте EJB. Те обработват транзакциите декларативно.   -  person JB Nizet    schedule 21.04.2013
comment
Благодаря JB Nizet, прав си. Но пак нещо не разбирам.   -  person robson    schedule 22.04.2013
comment
Добре, актуализирах въпроса си (и изтрих отговора - прав си)   -  person robson    schedule 22.04.2013


Отговори (1)


Добре, така че е възможно да се направи CDI bean tansactional - с прехващачи :-)

Най-накрая успях да разреша проблема си, като прочетох тази статия:

http://smokeandice.blogspot.com/2009/12/cdi-and-declarative-transactions.html

Редактиране:

От JEE7 има нова анотация @Transactional, която приема всички JPA действия в CDI bean или метод в транзакция.

person robson    schedule 23.04.2013