JTA EntityManager без ручных коммитов

Я пытаюсь вывести свой проект из шва 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-бин танзакционным - с перехватчиками :-)

Наконец мне удалось решить мою проблему, прочитав эту статью:

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

Изменить:

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

person robson    schedule 23.04.2013