How to inject mock datasource when using in Junit test - spring

In my application,we bind the datasource through the JNDIlook up using below code:
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/jboss/datasources/efmDS</value>
</property>
</bean>
Dao has code like below:
#Autowired
#Qualifier("jndiDataSource")
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
Now I am having problem while running Junit test case.
I am testing a service method which is annotated with #Transactional.
This service method internally calls some dao method which I have already mocked using mockito but I am facing issues as when transaction is getting started it tries to fetch connection from datasource which is not present and throws communicationslinkfailure exception
How can I mock datasource in this case ? or any other alternative to solve the issue is also appreciated ?

Related

Mocked object in a whole spring Batch test

I want to test a whole Spring Batch but Ihave a problem. I have a service to delete rows in a DB and in a LDAP.
For the BD I have implemented a H2 in-memory database so no problems.
For the LDAP it's more difficult to have a in-memory LDAP so I want to fake the DAO LDapRepository calling method "delete" (LDapRepository is the interface and LDapRepositoryImpl annotated by #Repository the implementation)
So I tried to inject a mock in my configuration but it doesn't work.
The test fails with a null pointer exception when I try to make the fake call ldapRepository.removePerson (so ldapRepository is not correctly injected).
How is it possible to substitute the bean LDapRepository in my configuration ?
Here's the test code :
#ContextConfiguration(locations = {"classpath:purge/job-test.xml"})
public class PurgeJobTest {
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#InjectMocks
#Qualifier(value = "ldapRepositoryImpl")
private LdapRepository ldapRepository;
#Test
public void testExampleJob() throws Exception {
Mockito.doNothing().when(ldapRepository.removePerson(any(String.class)));
JobParameters jobParameters = new JobParametersBuilder()
.addString("fichierJob", "/purge/job-test.xml")
.addString("nomJob", "purgeJob").toJobParameters();
JobExecution exec =jobLauncherTestUtils.launchJob(jobParameters);
assertEquals(BatchStatus.COMPLETED, exec.getStatus());
}
}
OK so I admit my question was a little tricky but I want to share the answer to other people who faced a similar problem.
The null pointer exception was quite logic. Indeed the bean was not recognized in the context because nowhere it was correctly injected in it.
It's a common pitfall related by example in this post Injecting Mockito Mock objects using Spring JavaConfig and #Autowired.
or this other post : Injecting Mockito mocks into a Spring bean
So in my job-test.xml I commented the component-scan in which my "real" LdapRepository" and LdapRepositoryImpl were declared and replace them with :
<bean id="ldapRepository" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="purge.batch.repository.LdapRepository" />
</bean>
<bean id="ldapRepositoryImpl" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="purge.batch.repository.LdapRepositoryImpl" />
</bean>
(I could have place these bean declaration before the component-scan to give it priority)
And that works like a charm !

How entity manager is injected from localcontainerEntityManagerFactoryBean

I was searching for how entity manager is injected into DAO classes when I configure LocalContainerEntityManagerFactoryBean class in spring.
class OrderDAOImpl {
#PersistenceContext
private EntityManager entityManager
//....DAO Methods...
}
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
.....
</bean>
From this bean, how spring creates entityManager.
I was searching the same reason for hibernate's session factory and I found Here that getObject method will inject sessionFactory. But same is not the case with LocalContainerEntityManagerFactoryBean. Can some one please help me understand how this entityManager is injected in JPA?

Spring and Hibernate save not working

I am using Hibernate and Spring 3.0 i am trying to save the value into database but when i see a console the only select query is showing insert or update is not showing and save is not working
I created a sessionFactory bean and inject it into Impl
<bean id="GetStartedDAOBean" class="com.sample.dao.impl.GetStartedDAOImpl" >
<property name="sessionfactory" ref="sessionFactory">
</property>
</bean
<bean id="GetStartedActionBean" class="com.sample.action.GetStartedAction">
<property name="getStartedDAOImpl" ref="GetStartedDAOBean"></property>
<property name="industryDAOImpl" ref="IndustryDAOBean"></property>
<property name="stateDAOImpl" ref="stateDAOBean"></property>
</bean>
In impl i have
private SessionFactory sessionfactory;
public void setSessionfactory(SessionFactory sessionfactory) {
this.sessionfactory = sessionfactory;
}
public void save(Customer customer)throws IllegalStateException,SystemException{
try {
sessionfactory.openSession().saveOrUpdate(customer);
}
catch(Exception e){
e.printStackTrace();
}
}
when i debug there is value in sessionFactory but it does not save any value. and also does not show any inserted query. There is no error.
Any one can help me?
You open your session (in-memory) and save something onto it, but the session saves in the database only when you flush(). Do a
Session session = sessionfactory.openSession();
session.saveOrUpdate(customer);
session.flush();
Another way is to commit the transaction, and thus Hibernate will automatically call flush().
Try with #Transactional at the method, and add the following to your XML:
<tx:annotation-driven/>
#Transaction you have give on method of service class and <tx:annotation-driven/> you have to give in applicaiton-context.xml file.
Hence, when any one call the service class's method, the transaciton will start by spring and it will handle up to commit and rollback.

Another question on Spring 3, servlet, #autowired

I think I've read every question and answer on Spring and autowiring a servlet, both here and at springsource.org, and I still can't get it working.
All I want to do is have the datasource automatically set in my servlets. I understand that the container creates the servlet and not Spring.
Here is code from my test servlet:
package mypackage.servlets;
imports go here...
#Service
public class TestServlet extends HttpServlet
{
private JdbcTemplate _jt;
#Autowired
public void setDataSource(DataSource dataSource)
{
_jt = new JdbcTemplate(dataSource);
}
etc etc
In my applicationContext.xml I have:
<context:annotation-config />
<context:component-scan base-package="mypackage.servlets />
<import resource="datasource.xml" />
and in my datasource.xml:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/db" />
If I can't get this working I'll just use WebApplicationContextUtils in the servlet's init method but I'd really like to make this work after all the reading I've been doing.
I'm using Spring 3, Java 1.6.
Thanks,
Paul
You need to replace your Servlets by Spring MVC contollers. Because Spring will not inject anything the classes (servlets) created by someone else then Spring itselfe (except #Configurable).
(To get an very simple example, take a look at the STS Spring Template Project: MVC).
What I wanted to do was get a DataSource reference in my Servlet for free, i.e. not calling a static getDatasource method on some class.
Here's what I learned and how I got it working:
Servlets cannot be configured or autowired by Spring. Servlets are created before Spring's app context is loaded. See issue SPR-7801: https://jira.springsource.org/browse/SPR-7801
What I did was create a DataSource in my applicationContext.xml and export that as a property:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/db" />
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="myDatasource">
<ref bean="dataSource"/>
</entry>
</map>
</property>
</bean>
In my servlet's init method I read the property:
public void init(ServletConfig config)
{
Object obj = config.getServletContext().getAttribute("myDatasource");
setDataSource((DataSource)obj);
}
public void setDataSource(DataSource datasource)
{
// do something here with datasource, like
// store it or make a JdbcTemplate out of it
}
If I'd been using DAOs instead of hitting the database from the servlets it would have been easy to wire them up for #Autowired by marking them #Configurable, and also be able to use #Transactional and other Spring goodies.

Ability to switch Persistence Unit dynamically within the application (JPA)

My application data access layer is built using Spring and EclipseLink and I am currently trying to implement the following feature - Ability to switch the current/active persistence unit dynamically for a user. I tried various options and finally ended up doing the following.
In the persistence.xml, declare multiple PUs. Create a class with as many EntityManagerFactory attributes as there are PUs defined. This will act as a factory and return the appropriate EntityManager based on my logic
public class MyEntityManagerFactory {
#PersistenceUnit(unitName="PU_1")
private EntityManagerFactory emf1;
#PersistenceUnit(unitName="PU_2")
private EntityManagerFactory emf2;
public EntityManager getEntityManager(int releaseId) {
// Logic goes here to return the appropriate entityManeger
}
}
My spring-beans xml looks like this..
<!-- First persistence unit -->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emFactory1">
<property name="persistenceUnitName" value="PU_1" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager1">
<property name="entityManagerFactory" ref="emFactory1"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager1"/>
The above section is repeated for the second PU (with names like emFactory2, transactionManager2 etc).
I am a JPA newbie and I know that this is not the best solution. I appreciate any assistance in implementing this requirement in a better/elegant way!
Thanks!
First of all thanks to user332768 and bert. I tried using AbstractRoutingDataSource as mentioned in the link provided by bert, but got lost trying to hook up my jpa layer (eclipselink). I reverted to my older approach with some modifications. The solution looks cleaner (IMHO) and is working fine. (switching database at runtime and also writing to multiple databases in the same transaction)
public class MyEntityManagerFactoryImpl implements MyEntityManagerFactory, ApplicationContextAware {
private HashMap<String, EntityManagerFactory> emFactoryMap;
public EntityManager getEntityManager(String releaseId) {
return SharedEntityManagerCreator.createSharedEntityManager(emFactoryMap.get(releaseName));
}
#Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
Map<String, LocalContainerEntityManagerFactoryBean> emMap = applicationContext.getBeansOfType(LocalContainerEntityManagerFactoryBean.class);
Set<String> keys = emMap.keySet();
EntityManagerFactory entityManagerFactory = null;
String releaseId = null;
emFactoryMap = new HashMap<String, EntityManagerFactory>();
for (String key:keys) {
releaseId = key.split("_")[1];
entityManagerFactory = emMap.get(key).getObject();
emFactoryMap.put(releaseId, entityManagerFactory);
}
}
}
I now inject my DAO's with an instance (singleton) of MyEntityManagerFactoryImpl. The dao will then simply call createSharedEntityManager with the required release and will get the correct EntityManager for that database. (Note that i am now using application managed EntityManager and hence i have to explicitly close them in my dao)
I also moved to jta transaction manager (to manage transaction across multiple databases)
This is how my spring xml looks like now.
...
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel1">
<property name="persistenceUnitName" value="PU1" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel2">
<property name="persistenceUnitName" value="PU2" />
</bean>
<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="jtaTransactionManager">
</bean>
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
....
Cheers! (comments are welcome)
I am not sure if this is a clean method. Instead of declaring the enitiymanagerfactory multiple times, we can use the spring application context to get the entitymanagerfactory declared in the spring application.xml.
hm = applicationContext.getBeansOfType(org.springframework.orm.jpa.LocalEntityManagerFactoryBean.class);
EntityManagerFactory emf = ((org.springframework.orm.jpa.LocalEntityManagerFactoryBean) hm.get("&emf1")).getNativeEntityManagerFactory();
EntityManagerFactory emf2 = ((org.springframework.orm.jpa.LocalEntityManagerFactoryBean) hm.get("&emf2")).getNativeEntityManagerFactory();
This is something i need to do in the future too, for this i have bookmarked Spring DynamicDatasourceRouting
http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
As far as i understand, this is using one PU, which gets assigned different DataSources. Perhaps it is helpful.

Resources