简体   繁体   English

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

[英]Spring 4 + HIbernate 4 + Junit @Transactional nativeSQL query

Hi I've a problem with Spring Hibernate session management in some JUnit tests. 嗨,我在某些JUnit测试中遇到了Spring Hibernate会话管理问题。

I have a test class signed as @Transactional in order to have the autorollback feature for each test method; 我有一个签名为@Transactional的测试类,以便为每个测试方法提供自动回滚功能; during a test i insert three rows into the database and then run a native query (using session.createSQLQuery()) which should return a list containing all three elements i've just saved, but the result of the native query is always empty. 在测试过程中,我将三行插入数据库,然后运行本机查询(使用session.createSQLQuery()),该查询应返回一个包含我刚刚保存的所有三个元素的列表,但本机查询的结果始终为空。

I've tryied to remove @Transactional from test class so the insert process will end with a commit, in this scenario my native query works perfectly and the test is green but no rollback is perfomed (due to the lack of @Transactional). 我试图从测试类中删除@Transactional,以便插入过程将以提交结束,在这种情况下,我的本机查询可以正常工作,并且测试是绿色的,但是没有回滚(由于缺少@Transactional)。

Personally I would prefer to not sign test with @Rollback(false) and remove the data manually so I was wondering if this strange behavior was caused by incorrect configuration. 我个人不希望不使用@Rollback(false)进行测试签名并手动删除数据,因此我想知道这种奇怪的行为是否是由于错误的配置引起的。

Thanks in advance. 提前致谢。

Below my Spring session and transaction manager configuration, incriminated test and native query under test. 在我的Spring会话和事务管理器配置下,进行了隐式测试和被测本机查询。

Spring Config: 弹簧配置:

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

Method under Test 被测方法

@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);

    }

Test code: 测试代码:

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

Have had similar issue. 发生过类似的问题。 Entities could not have been removed from H2 in mem during transactional test method invocation. 在事务性测试方法调用期间,无法从内存中的H2中删除实体。 Fixed it flushing current session within removal DAO method. 修复了在清除DAO方法中刷新当前会话的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM