Я использую 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?
Большое спасибо за любую информацию или рекомендации.