I got following query which gives zero results in unit test when using EntityManager implementation listDailyExpenses(). However if I use the listDailyExpensesNonEm() implantation within test, I get correct result count. Why does it behave differently?
Hibernate query which generate for both methods are identical.
And this issue only occur during unit test, through the web application both methods produce same results.
SampleTest.java
@SpringBootTest(classes = TestAppContext.class)
@Sql({ "/test-data.sql" })
public class SampleTest {
@Autowired
DailyExpensesDao dailyExpensesDao;
// **** this test fail
@Test
void testListExpenses() {
List<DailyExpense> list = dailyExpensesDao.listDailyExpenses();
assertEquals(5, list.size());
}
}
DailyExpensesDaoImpl.java - Implementation of two methods
@Repository
@Transactional
public class DailyExpensesDaoImpl extends AbstractHibernateDao<DailyExpense> implements DailyExpensesDao {
private static final Logger logger = LogManager.getLogger(DailyExpensesDaoImpl.class);
public DailyExpensesDaoImpl() {
super();
setClazz(DailyExpense.class);
}
@Override
public List<DailyExpense> listDailyExpenses() {
EntityManager entityManager = getCurrentSession().getEntityManagerFactory().createEntityManager();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<DailyExpense> criteriaQuery = criteriaBuilder.createQuery(DailyExpense.class);
Root<DailyExpense> root = criteriaQuery.from(DailyExpense.class);
criteriaQuery.select(root);
TypedQuery<DailyExpense> typedQuery = entityManager.createQuery(criteriaQuery);
List<DailyExpense> list = typedQuery.getResultList();
return list;
}
@Override
public List<DailyExpense> listDailyExpensesNonEm() {
List<DailyExpense> list = getCurrentSession().createQuery("from DailyExpense").list();
logger.debug("listPersons size of items " + list.size());
return list;
}
TestAppContext.java - Test Configuration class
@Configuration
@PropertySource("classpath:test-database.properties")
@EnableTransactionManagement
@ComponentScan(basePackages = {
"org.d.money.dao", "org.d.money.service", "org.d.money.model"
})
public class TestAppContext {
private static final Logger logger = LogManager.getLogger(TestAppContext.class);
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
logger.debug("getting session fac");
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] {
"org.decserv.money.model"
});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
//https://stackoverflow.com/questions/21574236/how-to-fix-org-hibernate-lazyinitializationexception-could-not-initialize-prox
properties.put("hibernate.enable_lazy_load_no_trans", environment.getRequiredProperty("hibernate.enable_lazy_load_no_trans"));
return properties;
}
@Bean
public HibernateTransactionManager getTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
Here is my hibernate properties
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.enable_lazy_load_no_trans", true);
return properties;
}
Using
hibernate 5.6.8.Final
org.springframework.boot 2.7.4