Testen mit EntityManager und Transaktionen
Immer wieder erlebe ich es, dass in Tests mit EntityManager Transaktionen gestartet und comitted werden. Allerdings gibt es kein Exception-Handling, sodass kein Rollback ausgeführt wird. Schlimmer noch: Die Transaktion wird nicht beendet und andere Tests schlagen ebenfalls fehl.
Um das zu verhindern, verwende ich ein solches Util:
public class TestUtil {
public static <ENTITY_TYPE> ENTITY_TYPE getEntity(EntityManager entityManager, Class<ENTITY_TYPE> classType, Long id) {
Query query = entityManager.createQuery("SELECT o FROM " + classType.getSimpleName() + " o");
return (ENTITY_TYPE) query.getSingleResult();
}
public static <ENTITY_TYPE> void persistInTransaction(EntityManager entityManager, ENTITY_TYPE entity) {
executeInTransaction(entityManager, () -> entityManager.persist(entity));
}
public static void executeInTransaction(EntityManager entityManager, TransactionExecutor transactionExecutor) {
try {
entityManager.getTransaction().begin();
transactionExecutor.executeInTransaction();
entityManager.getTransaction().commit();
} catch (RuntimeException e) {
if (entityManager.getTransaction().isActive()) {
entityManager.getTransaction().rollback();
}
throw e;
}
}
@FunctionalInterface
public interface TransactionExecutor {
void executeInTransaction();
}
}