Hibernate 如何在junit运行时测试期间使用多个datasouce和sessionFactory
如何在junit运行时测试期间使用多个datasouce和sessionFactory 我使用HibernateDataTemplate进行持久化,我的结构如下所示: 我只想从不同的数据库获取产品,然后在ProductStatServiceTest运行时将它们持久化到不同的数据库 提前谢谢Hibernate 如何在junit运行时测试期间使用多个datasouce和sessionFactory,hibernate,spring,junit,sessionfactory,Hibernate,Spring,Junit,Sessionfactory,如何在junit运行时测试期间使用多个datasouce和sessionFactory 我使用HibernateDataTemplate进行持久化,我的结构如下所示: 我只想从不同的数据库获取产品,然后在ProductStatServiceTest运行时将它们持久化到不同的数据库 提前谢谢 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/dataSource.xml", "/hibernat
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/dataSource.xml", "/hibernate.xml", "/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
public abstract class GenericTransactionalUnitTest extends AbstractTransactionalJUnit4SpringContextTests {
private Session session;
protected abstract SessionFactory getSessionFactory();
...
}
@Transactional(readOnly = true)
abstract public class ProductStatUnitTest extends GenericTransactionalUnitTest {
@Autowired
@Qualifier(value = "productStatSessionFactory")
private SessionFactory sessionFactory;
@Resource(name = "productStatDS")
public void setDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
@Override
protected SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class ProductStatServiceTest extends ProductStatUnitTest {
@Autowired
private ProductStatService productStatService;
@Test
public List<ProductStat> testInjection() throws ParseException {
productStatService.findById(123456);
}
..
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“/dataSource.xml”、“/hibernate.xml”、“/applicationContext.xml”})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@TransactionConfiguration(transactionManager=“txManager”,defaultRollback=true)
公共抽象类GenericTransactionalUnitTest扩展了AbstractTransactionalJUnit4SpringContextTests{
非公开会议;
受保护的抽象SessionFactory getSessionFactory();
...
}
@事务(只读=真)
抽象公共类ProductStationTest扩展了GenericTransactionalUnitTest{
@自动连线
@限定符(value=“productStatSessionFactory”)
私人会话工厂会话工厂;
@资源(name=“productStatDS”)
public void setDataSource(数据源数据源){
super.setDataSource(数据源);
}
@凌驾
受保护的SessionFactory getSessionFactory(){
返回工厂;
}
}
公共类ProductStatServiceTest扩展了ProductStationTest{
@自动连线
私人产品StatService产品StatService;
@试验
public List testInjection()引发ParseException异常{
productStatService.findById(123456);
}
..
}
2数据库=>2个会话工厂和数据源。这在您的代码中目前是不可能的
我假设您有1个ProductStatService
,但您的要求是该服务将与sessionfactoryA一起用于“选择”,与sessionfactoryB一起用于“插入”
因此,您需要在单元测试中创建(并注入)该服务的2个实例,当然这些实例不能作为单例(假设您将Spring用于DI)。您必须重写一些代码,实际的sessionfactory需要注入到服务中,而不是由
GenericTransactionalUnitTest.getSessionFactory()
检索
更新
如果您不想创建2个DAO,那么这也是一个选项:
public class ProductStatDAO extends AbstractHibernateDao {
@Autowired(required = false)
@Qualifier("sessionFactoryA")
private SessionFactory sessionFactoryA;
@Autowired(required = false)
@Qualifier("sessionFactoryB")
private SessionFactory sessionFactoryB;
//called by Spring (init-method)
public void init() {
if (getSessionFactory() == null) {
if (sessionFactoryA != null) {
setSessionFactory(sessionFactoryA);
} else if (sessionFactoryB != null) {
setSessionFactory(sessionFactoryB);
}
// else throw exception
}
}
}
但是,您仍然需要在您的服务中注入此DAO的两个不同实例(所以scope='prototype')。2数据库=>2个会话工厂和数据源。这在您的代码中目前是不可能的 我假设您有1个
ProductStatService
,但您的要求是该服务将与sessionfactoryA一起用于“选择”,与sessionfactoryB一起用于“插入”
因此,您需要在单元测试中创建(并注入)该服务的2个实例,当然这些实例不能作为单例(假设您将Spring用于DI)。您必须重写一些代码,实际的sessionfactory需要注入到服务中,而不是由
GenericTransactionalUnitTest.getSessionFactory()
检索
更新
如果您不想创建2个DAO,那么这也是一个选项:
public class ProductStatDAO extends AbstractHibernateDao {
@Autowired(required = false)
@Qualifier("sessionFactoryA")
private SessionFactory sessionFactoryA;
@Autowired(required = false)
@Qualifier("sessionFactoryB")
private SessionFactory sessionFactoryB;
//called by Spring (init-method)
public void init() {
if (getSessionFactory() == null) {
if (sessionFactoryA != null) {
setSessionFactory(sessionFactoryA);
} else if (sessionFactoryB != null) {
setSessionFactory(sessionFactoryB);
}
// else throw exception
}
}
}
但是,您仍然需要在您的服务中注入此DAO的两个不同实例(所以scope='prototype')。首先谢谢。如何在一个测试类中注入不同的会话工厂?您是否建议将sessionFactory保留在服务类而不是测试类中?那么如何设置不同的数据源?实际上,sessionFactory都不是在DAO级别使用的;您的服务甚至不应该知道hibernate用于持久性。最好的选择可能是有2个DAO(一个用于检索,一个用于持久化productstats),并在其中注入不同的sessionfactory(一个配置为DB-a,一个配置为DB-B)。请注意,除非您有真正的(J2EE)事务管理器(如Websphere或JBoss),否则不能在一个事务中使用2个DB。如果您使用Tomcat或Jetty,您必须集成Atomikos才能实现这一点。首先谢谢。如何在一个测试类中注入不同的会话工厂?您是否建议将sessionFactory保留在服务类而不是测试类中?那么如何设置不同的数据源?实际上,sessionFactory都不是在DAO级别使用的;您的服务甚至不应该知道hibernate用于持久性。最好的选择可能是有2个DAO(一个用于检索,一个用于持久化productstats),并在其中注入不同的sessionfactory(一个配置为DB-a,一个配置为DB-B)。请注意,除非您有真正的(J2EE)事务管理器(如Websphere或JBoss),否则不能在一个事务中使用2个DB。如果您使用Tomcat或Jetty,则必须集成Atomikos才能实现这一点。