【问题标题】:how to use multiple datasouce and sessionFactory during a junit runtime test如何在 junit 运行时测试期间使用多个数据源和 sessionFactory
【发布时间】:2011-12-18 14:48:20
【问题描述】:

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

我使用 hibernateDaoTemplate 进行持久化,我的结构就在这里:

我只想从不同的数据库中获取产品,然后在 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); 
  }
..
 }

【问题讨论】:

    标签: hibernate spring junit sessionfactory


    【解决方案1】:

    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 的 2 个不同实例(因此 scope='prototype')。

    【讨论】:

    • 首先谢谢。如何在一个测试类中注入不同的会话工厂?您是否建议将 sessionFactory 保留在服务类而不是测试类中?
    • 那我该如何设置不同的数据源呢?
    • 实际上,sessionfactory 也不是在 DAO 级别使用的;您的服务甚至不应该知道休眠用于持久性。最好的选择可能是拥有 2 个 DAO(一个用于检索,一个用于持久化 productstats)并在其中注入一个不同的 sessionfactory(一个为 DB-A 配置,一个为 DB-B 配置)。请注意,除非您拥有真正的 (J2EE) 事务管理器(例如在 Websphere 或 JBoss 上),否则不能在 1 个事务中使用 2 个 DB。如果您使用 Tomcat 或 Jetty,则必须集成 Atomikos 以允许这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多