JPA/EclipseLink: EntityManager.getTransaction() создает новую транзакцию или возвращает активную?

Я использую EclipseLink 2.3.0. У меня есть метод, который я вызываю из модульного теста (следовательно, вне контейнера, без JTA), который выглядит следующим образом:

EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();

Изменения НЕ сохранялись в базе данных, и я рассматривал это в течение длительного времени и, наконец, понял, что EntityManager.getTransaction() фактически возвращает НОВУЮ EntityTransaction, а не одну и ту же в обоих вызовах. В результате первый вызов создает новую транзакцию и начинает ее, а второй вызов создает ДРУГУЮ транзакцию и фиксирует ее. Поскольку первая транзакция так и не была зафиксирована, изменения не сохраняются. Мы проверили это следующим образом:

log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());

Что привело к следующим сообщениям в журнале:

INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@1e34f445
INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@706a4d1a

Два разных идентификатора объекта подтверждают наличие двух разных экземпляров. Изменение кода на этот:

EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();

... устранило проблему. Теперь, когда я запускаю код, я вижу операторы SQL, сгенерированные для работы с базой данных, и глядя в базу данных, данные были изменены.

Я был немного удивлен таким результатом, так как я видел множество примеров кода в Интернете (для JPA в целом и для EclipseLink в частности), которые рекомендуют код, который мы использовали для управления транзакциями. Я искал повсюду информацию конкретно об этом, но ничего не нашел.Итак, что происходит?

Я искал в спецификации JPA что-то, что точно указывает, что делает getTransaction(), и не было указано, является ли транзакция новой или той же самой. Есть ли параметр в файле persistence.xml, который управляет этим? Является ли поведение специфичным для каждой реализации спецификации JPA?

Большое спасибо за любую информацию или рекомендации.

13
задан Uncle Long Hair 13 June 2012 в 11:51
поделиться