Spring 4 + HIbernate 4 + Junit @Transactional nativeSQL 查询

Spring 4 + HIbernate 4 + Junit @Transactional nativeSQL query

您好,我在一些 JUnit 测试中遇到了 Spring Hibernate 会话管理的问题。

我有一个测试 class 签名为 @Transactional 以便为每个测试方法提供自动回滚功能;在测试期间,我将三行插入数据库,然后 运行 一个本机查询(使用 session.createSQLQuery()),它应该 return 一个包含我刚刚保存的所有三个元素的列表,但是本机查询的结果始终为空。

我已经尝试从测试中删除@Transactional class 因此插入过程将以提交结束,在这种情况下我的本机查询完美运行并且测试是绿色的但没有执行回滚(由于由于缺少@Transactional)。

就我个人而言,我宁愿不使用@Rollback(false) 签署测试并手动删除数据,所以我想知道这种奇怪的行为是否是由不正确的配置引起的。

提前致谢。

在我的 Spring 会话和事务管理器配置下,涉及测试和正在测试的本机查询。

Spring 配置:

@Bean(name = "sessionFactory")
@Autowired
public SessionFactory getSessionFactory(final DataSource dataSource) throws Exception {
        final LocalSessionFactoryBuilder springSessionFactoryBean = new LocalSessionFactoryBuilder(dataSource);
        springSessionFactoryBean.addAnnotatedClasses(CvSentEvent.class);

        final Properties hibernateProperties = new Properties();
        hibernateProperties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
        hibernateProperties.put("hibernate.cache.use_second_level_cache", true);
        hibernateProperties.put("hibernate.hbm2ddl.auto", "validate");
        hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        hibernateProperties.put("hibernate.format_sql", false);
        hibernateProperties.put("hibernate.jdbc.use_scrollable_resultsets", true);
        hibernateProperties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
        hibernateProperties.put("org.hibernate.cache.ehcache.configurationResourceName", "ehcache.xml");

        springSessionFactoryBean.addProperties(hibernateProperties);

        return springSessionFactoryBean.buildSessionFactory();
    }

正在测试的方法

@Override
@Transactional(readOnly = true)
public List<CvSentReport> searchByWebsiteAccount(final String website, final String account, final String cvs, final String budgetFIlter) {
        final String sql = ""
                + "select sent, website, account from (select "
                + "    sum(c.count) as sent, "
                + "    c.website, "
                + "    c.sponsoraccountname as account "
                + " from "
                + "    cvsentevents c "
                + " where "
                + "    c.website like :website "
                + "    and (c.sponsoraccountname like :account or (c.sponsoraccountname IS NULL and :account = '%%')) "
                + " group by "
                + "    c.website, "
                + "    c.sponsoraccountname ) z " + filterForCVs(cvs) + ";";

        final List<Object> list = new ArrayList<Object>();

        @SuppressWarnings("unchecked")
        final List<Object> itemList = getSession()
                .createSQLQuery(sql)
                .setParameter("website", "%" + website + "%")
                .setParameter("account", "%" + account + "%")
                .list();

        list.addAll(itemList);

        return createAListOfCvSentReports(budgetFIlter, list);

    }

测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { SpringJunitContext.class })
@Transactional
public class CvSentEventDaoTest {

    @Autowired
    private CvSentEventDao sut;

   @Test
    public void findAllTheItems() {
        newCvSentEvent(0, "website1", "account1", "1");
        newCvSentEvent(1, "website2", "account2", "1");
        newCvSentEvent(1, "website3", "account3", "0");

        final List<CvSentReport> actual = sut.searchByWebsiteAccount("website", "account", "all", "all");

        assertEquals(3, actual.size());
    }
}

遇到过类似的问题。在事务测试方法调用期间,无法从内存中的 H2 中删除实体。修复了在删除 DAO 方法中刷新当前会话的问题。