javatar
javatar

Reputation: 4621

how to use multiple datasouce and sessionFactory during a junit runtime test

How to use multiple datasouce and sessionFactory during a junit runtime test?

I use hibernateDaoTemplate for persistence, and my structure is right down here:

I just want to get, say, products from a different db and then persist them to a different db in ProductStatServiceTest runtime.

Thanks in advance.

@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); 
  }
..
 }

Upvotes: 0

Views: 4086

Answers (1)

Stijn Geukens
Stijn Geukens

Reputation: 15628

2 Database => 2 session factories and datasources. This currently is not possible in your code.

I assume you have 1 ProductStatService but your requirement is that this service will work with sessionfactoryA for the 'select' and sessionfactoryB for the 'insert'.

Hence, you will need to create (and inject) 2 instances of this service in your unit test and these of course can't be scoped as singletons (assuming you use Spring for DI).
You will have to rewrite some of your code, the actual sessionfactory will need to be injected into the service and not retrieved by GenericTransactionalUnitTest.getSessionFactory().

UPDATE

If you don't want to create 2 DAO's then this also an option:

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
    }
}

}

You will however still need to inject 2 different instances of this DAO (so scope='prototype') in your service.

Upvotes: 3

Related Questions