Hibernate 如何在junit运行时测试期间使用多个datasouce和sessionFactory

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

如何在junit运行时测试期间使用多个datasouce和sessionFactory

我使用HibernateDataTemplate进行持久化,我的结构如下所示:

我只想从不同的数据库获取产品,然后在ProductStatServiceTest运行时将它们持久化到不同的数据库

提前谢谢

@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才能实现这一点。