【发布时间】:2019-05-06 08:42:46
【问题描述】:
我对hibernate有点陌生,所以我从简单的事情开始。
根据 F.I.R.S.T 测试原则,单元测试必须是 I - 隔离的。
我正在尝试使用@Transactional 注释将其应用于存储库层(Hibernate\JPA)的集成测试:
@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;
}
}
但是,就事务中执行的两种方法而言,hibernate 并没有实际执行它们(据我了解)- 至少 日志中没有与 insert 的行。
如果我通过将脚本添加到嵌入式数据源来运行数据插入,例如:
INSERT INTO employee (employee_id, employee_name) VALUES (1, 'name');
并尝试使用相同的 id 但新名称保存员工,测试将成功。这对我来说是最令人困惑的事情。
我看到了一个自动装配EntityManager 的解决方案并将其称为flush() 方法。但我不喜欢它,因为我尝试编写测试而不绑定到 Hibernate\JPA。
我也尝试了不同的flushMode,但也没有用。
Q1:有没有办法让 Hibernate 在调用存储库的方法后立即运行查询?
Q2:在保存/更新/删除存储库方法中显式调用EntityManager#flush 是一种好习惯吗?
我的员工:
@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)
}
和 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;
}
}
【问题讨论】:
标签: java spring hibernate junit