I'm a little bit new to hibernate, so I started with simple things.
According to F.I.R.S.T test principles, unit tests must be I - isolated. I'm trying to apply it to integration tests for repository layer (Hibernate\JPA) using @Transactional annotation:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RepositoryConfig.class) @Transactional public class EmployeeRepositoryTest extends AbstractRepositoryTest { @Autowired private IEmployeeRepository employeeRepository; @Test public void saveTest() { Employee expectedEmployee = buildEmployee(1, "Parker"); employeeRepository.save(expectedEmployee); Employee actualEmployee = employeeRepository.findById(1); assertEquals(expectedEmployee, actualEmployee); } private Employee buildEmployee(long id, String name) { Employee employee = new Employee(); employee.setId(id); employee.setName(name); return employee; } } However, as far as two methods are performed within a transaction, hibernate does not actually perform them (as I understand it) - at least there's no line with insert in logs.
If I run data insertion by adding a script to embeded datasourse like:
INSERT INTO employee (employee_id, employee_name) VALUES (1, 'name'); and try to save employee with the same id but new name, the test will success. And that's the most confusing thing for me.
I saw a solution with autowiring EntityManager and calling it's flush() method. But I don't like it, since I try to write tests without being tied to Hibernate\JPA.
I also tried different flushMode, but it didn't help either.
Q1: Is there a way to make Hibernate run queries right after repository's method is called?
Q2: Is it a good practice to call EntityManager#flush in save/update/delete repository methods explicitly?
My Employee:
@Entity @Table(name = "employee") public class Employee { @Id @Column(name = "employee_id") private long id; @Column(name = "employee_name") private String name; // the rest required things (constructor, getters/setters and etc) } and RepositoryConfig:
@Configuration @EnableTransactionManagement @ComponentScan("org.my.package") public class RepositoryConfig { @Bean public DataSource getDataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .build(); } @Bean public JpaTransactionManager transactionManager() { return new JpaTransactionManager(); } @Bean @Autowired public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) { return new HibernateTemplate(sessionFactory); } @Bean public LocalSessionFactoryBean getSessionFactory() { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(getDataSource()); sessionFactory.setPackagesToScan("org.my.package.model"); sessionFactory.setHibernateProperties(getHibernateProperties()); return sessionFactory; } private Properties getHibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.dialect", "H2Dialect"); properties.put("hibernate.show_sql", true); return properties; } }