Reputation: 4621
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
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