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();
        }
}