Ich verwende die "JBoss Quickstart" -Tutorial beschrieben here. Es zeigt die Verwendung von verteilten Transaktionen einschließlich JPA in eigenständigen Anwendungen.Standalone JTA 1.2 und Hibernate: JPA läuft nicht zurück?
Ich habe den Code heruntergeladen, läuft gut, alle Testfälle sind grün.
Es enthält folgenden Testfall:
@Test
public void testJpa() throws Exception {
System.out.println(testEntityRepository.save(new TestEntity("test1")));
System.out.println(testEntityRepository.save(new TestEntity("test2")));
System.out.println(testEntityRepository.save(new TestEntity("test3")));
org.junit.Assert.assertEquals(3, testEntityRepository.findAll().size());
}
Ich wollte diese interessanter machen, indem Sie eine Transaktion starten und es wieder vor dem assert, wie diese Walzen:
@Test
public void testJpa() throws Exception {
transactionManager.begin();
System.out.println(testEntityRepository.save(new TestEntity("test1")));
System.out.println(testEntityRepository.save(new TestEntity("test2")));
System.out.println(testEntityRepository.save(new TestEntity("test3")));
transactionManager.rollback();
org.junit.Assert.assertEquals(0, testEntityRepository.findAll().size());
}
Mit der rollback()
Ich würde erwarten, die findAll().size()
0
zurückgeben. Es wird jedoch weiterhin 3
zurückgegeben. Gibt es etwas, das mir fehlt? Die Möglichkeit, den JPA-Status zurückzusetzen, scheint eines der Hauptziele des Tutorials zu sein.
Der ursprüngliche Code für TestEntityRepository
:
public class TestEntityRepository {
@Inject
EntityManager entityManager;
@Transactional
public List<TestEntity> findAll() {
assert entityManager != null;
return (List<TestEntity>) this.entityManager.createQuery("select te from TestEntity te").getResultList();
}
@Transactional
public Long save(TestEntity testEntity) {
assert entityManager != null;
if (testEntity.isTransient()) {
entityManager.persist(testEntity);
entityManager.flush();
} else {
entityManager.merge(testEntity);
entityManager.flush();
}
return testEntity.getId();
}
}
Andere Code kann here finden.
Gibt es einen bestimmten Grund zu spülen nach Persistence und Merge? – Jaumzera
Bitte versuchen Sie dies: Verschieben Sie die Aufrufe von testEntityRepository.save zu einer Methode innerhalb von TestEntityRepository und rufen Sie sie über testJpa auf. – Jaumzera
@Jaumzera danke für deinen Vorschlag. Versucht, wie Sie vorgeschlagen haben, aber gleicher Effekt. Ich denke, die JPA-Transaktion ist irgendwie nicht korrekt mit der JTA-Transaktion verknüpft. Seltsamerweise, wenn ich "@ Transactional" durch "@Transactional (TxType.MANDATORY)" und 'entityManager.begin()' im Testfall ersetze, bekomme ich eine Ausnahme, die besagt, dass eine Transaktion erforderlich ist, die korrekt ist. – geert3