Używam EclipseLink 2.3.0. Mam metodę, która Wołam z testów jednostkowych (stąd na zewnątrz pojemnika, bez JTA), który wygląda tak:JPA/EclipseLink: Czy EntityManager.getTransaction() tworzy nową transakcję, czy zwraca aktywną?
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
Zmiany te nie są utrwalone w bazie danych, a wyglądało na to za od dłuższego czasu zorientował się, że EntityManager.getTransaction() faktycznie zwraca NOWY EntityTransaction, a nie ten sam w obu wywołaniach. Efekt jest taki, że pierwsze połączenie tworzy nową transakcję i rozpoczyna ją, a drugie połączenie tworzy INNĄ transakcję i zatwierdza ją. Ponieważ pierwsza transakcja nigdy nie została zatwierdzona, zmiany nie są zapisywane. Zweryfikowaliśmy to tak:
log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
co spowodowało w tych komunikatów dziennika:
INFO: org.ecl[email protected]1e34f445
INFO: org.ecl[email protected]706a4d1a
Dwa sprawdzeniu, że istnieją dwa różne instancje innego obiektu identyfikatora. Zmiana kodu na:
EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
... naprawiono problem. Teraz po uruchomieniu kodu widzę instrukcje SQL wygenerowane w celu wykonania pracy z bazą danych i po przejrzeniu w bazie danych dane zostały zmienione.
Byłem nieco zaskoczony tym wynikiem, ponieważ widziałem wiele przykładów kodu online (ogólnie dla JPA i dla EclipseLink), które polecają kod używany do zarządzania transakcjami. Szukałem dużo informacji o tym, ale niczego nie znalazłem. Więc co się dzieje?
Sprawdziłem specyfikację JPA pod kątem czegoś, co dokładnie określa, co robi getTransaction() i nie było to konkretne, jeśli transakcja jest nowa lub taka sama. Czy istnieje ustawienie w persistence.xml, które kontroluje to? Czy zachowanie jest specyficzne dla każdej implementacji specyfikacji JPA?
Dziękuję bardzo za wszelkie informacje lub wskazówki.
Może powinienem być bardziej zrozumiały - kod, który napisałem, NIE działa. Wprowadziłem zmiany w tym pytaniu w celu wyjaśnienia. –
Rozumiem to. Chodzi mi o to, że * powinien * działać, ponieważ specyfikacja JPA zawiera próbki kodu whet 'em.getTransaction()' jest używane do rozpoczynania i zatwierdzania transakcji. Musi to być błąd w EclipseLink, chyba że, jak już powiedziałem, kod pomiędzy początkiem i zatwierdzeniem już zatwierdza lub wycofuje transakcję. Moja odpowiedź nie jest rozwiązaniem twojego problemu, ale potwierdzeniem, że kod powinien zadziałać. Sugeruję zgłoszenie błędu do EclipseLink. –