Я использую EclipseLink 2.3.0. У меня есть метод, который я звоню из модульного теста (т.е. вне контейнера, не JTA), который выглядит следующим образом:JPA/EclipseLink: EntityManager.getTransaction() создает новую транзакцию или возвращает активную?
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
Изменения были не будучи сохранялись в базу данных, и смотрели на это для долгое время и, наконец, понял, что EntityManager.getTransaction() фактически возвращает NEW EntityTransaction, а не тот же самый в обоих вызовах. Эффект заключается в том, что первый вызов создает новую транзакцию и начинает ее, а второй вызов создает ДРУГОЕ транзакцию и фиксирует ее. Поскольку первая транзакция никогда не выполнялась, изменения не сохраняются. Мы проверили это так:
log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
Что в результате этих логов:
INFO: org.ecl[email protected]1e34f445
INFO: org.ecl[email protected]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?
Большое спасибо за любую информацию или руководство.
Возможно, я должен был быть более понятным - код, который я разместил, НЕ работает. Я внес изменения в вопрос, чтобы уточнить. –
Я понимаю это. Я хочу сказать, что он * должен * работать, поскольку спецификация JPA содержит примеры кода whet 'em.getTransaction()' используется для начала и фиксации транзакции. Таким образом, это должно быть ошибкой в EclipseLink, если, как я уже сказал, код между началом и коммитом уже совершает или откатывает транзакцию. Мой ответ не является решением вашей проблемы, а является подтверждением того, что код должен работать. Я предлагаю подавать ошибку EclipseLink. –