EntityManager - 在测试期间截断所有数据?

问题描述 投票:0回答:1

我正在使用较旧的测试设置,其中测试会相互影响,我正在尝试解决此问题。我认为截断测试之间的所有表就可以做到这一点,但我似乎无法让 EM 与该命令很好地配合,这就是代码的相关部分的样子:

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(...)
@ContextConfiguration(...)
public class MyTest {
    @PersistenceContext
    private EntityManager em;
    
    @After
    @Transactional // Current suite can't handle all tests being transactional
    public void after() {
        // ERROR: Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate
        em.createNativeQuery("SELECT CONCAT('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES").executeUpdate(); 
    }
}

我知道以这种方式使用executeUpdate()是不行的,但是我有哪些选项不会导致我必须复制粘贴大量行来显式删除每个表?

spring entitymanager
1个回答
0
投票

我找到了解决该问题的方法,不是最漂亮的,但至少有效:

@Autowired
private EntityManagerFactory emf;

@After
public void after() {
    EntityManager em = emf.createEntityManager(); // Need to create a new EM as the one managed by @PersistenceContext has been closed when we get here
    Transaction transaction = ((Session) em.getDelegate()).beginTransaction();
    em.getMetamodel().getEntities().stream().map(Type::getJavaType).forEach(entity -> truncateTable(em, entity));
    transaction.commit();
    em.close();
}

private <T> void truncateTable(EntityManager em, Class<T> entity) {
    CriteriaBuilder criteria = em.getCriteriaBuilder();
    CriteriaDelete<T> deleteCriteria = criteria.createCriteriaDelete(entity);
    deleteCriteria.from(entity);
    em.createQuery(deleteCriteria).executeUpdate();
}
© www.soinside.com 2019 - 2024. All rights reserved.