こんにちは、いくつかの JUnit テストで Spring Hibernate セッション管理に問題があります。
各テスト メソッドの自動ロールバック機能を使用するために、@Transactional として署名されたテスト クラスがあります。テスト中にデータベースに 3 つの行を挿入し、(session.createSQLQuery() を使用して) ネイティブ クエリを実行すると、保存した 3 つの要素すべてを含むリストが返されますが、ネイティブ クエリの結果は常に空です。
@Transactional をテスト クラスから削除して、挿入プロセスがコミットで終了するようにしました。このシナリオでは、ネイティブ クエリは完全に機能し、テストは緑色ですが、ロールバックは実行されません (@Transactional がないため)。
個人的には、 @Rollback(false) でテストに署名せず、手動でデータを削除したいので、この奇妙な動作が不適切な構成によって引き起こされたのではないかと考えていました。
前もって感謝します。
私の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());
}
}