We use Spring + iBatis in all of our DAO's to fetch data from Stored Procedures.
There are two main JNDI connections. one going to the datawarehouse
and another going to livedb
.
recently lot of SPs have been moved from the livedb to the datawarehouse and vice versa.
This is creating issues on the java side because:
Now, each DAO does not directly JUST relate to either datawarehouse or livedb. There might be methods in DAO A which relate to datawarehouse and others might relate to livedb. In order to do this we have to change the sqlMapClientTemplate
(because spring makes a dao have one to one mapping with JNDI connection). So we do this by:
this.setSqlMapClientTemplate(getSqlTemplDW()); //get connection to DW
getSqlMapClientTemplate().queryForList("dw_sps.somemapping", parmMap);
this.setSqlMapClientTemplate(getSqlTempl()); //set connection to live db
as you can see ...this is forcing us to have a lot of this same code in bunch of places.
Questions
Is it considered a design flaw to have one DAO talk to two different JNDI's? ( I know its not a design flaw in classic JDBC daos but is it different with Spring + iBatis?)
the getSqlTemplDW() method you see up there looks like:
public SqlMapClientTemplate getSqlTemplDW() {
SqlMapClient scl = (SqlMapClient) ApplicationInitializer.getApplicationContext().getBean("SqlMapClientDW");
DataSource dsc = (DataSource) ApplicationInitializer.getApplicationContext().getBean("DataSourceDW");
return new SqlMapClientTemplate(dsc, scl);
}
as you can see, I am using javax.sql.DataSource. However, we have been told to not use this import!! So now I am stuck. I cant use this import (meaning cant change connections in my DAO). So I've been getting suggestions that every dao should only have one to one mapping to the JNDI.
I want to know..is there a way around this at all?
Skeleton
spring-for-ibatis.xml
<bean id="datasource1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/RSRC/asdf/sdf/oltp"/>
</bean>
<bean id="datasource2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/RSRC/asdf/efs/dw"/>
</bean>
<bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sql-map-config-oracle.xml"/>
<property name="dataSource" ref="datasource1"/>
</bean>
<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sql-map-config-dw.xml"/>
<property name="dataSource" ref="datasource2"/>
</bean>
<!--dao bean-->
<bean id="examinationIfaceDAO" class="some.path.ExaminationIbatisDAO">
<property name="sqlMapClient" ref="sqlMapClient1"/>
<property name="dataSource" ref="datasource1"/>
</bean>
sql-map-config-oracle.xml
<sqlMapConfig>
<settings enhancementEnabled="true" useStatementNamespaces="true" />
<sqlMap resource="iBatis_file_with_sps_to_live_db.xml"/>
</sqlMapConfig>
sql-map-config-dw.xml
<sqlMapConfig>
<settings enhancementEnabled="true" useStatementNamespaces="true" />
<sqlMap resource="iBatis_file_with_sps_to_dw.xml" />
</sqlMapConfig>
Interface for Examination
public interface ExaminationIfaceDAO {
public boolean goToDW(String userId);
public boolean goToLiveDB(String userId);
}
ExaminationIbatisDAO
public class ExaminationIbatisDAO implements EexaminationIfaceDAO {
public boolean goToDW(String userId) {
HashMap paramMap = new HashMap();
paramMap.put("userId", userId);
//following line will break as it does not know about this mapping file
getSqlMapClientTemplate().queryForObject("iBatis_file_with_sps_to_dw.isAuthorized", paramMap);
return true;
}
public boolean goToLiveDB(String userId) {
HashMap paramMap = new HashMap();
paramMap.put("userId", userId);
//following line will be ok as it knows about this mapping file
getSqlMapClientTemplate().queryForObject("iBatis_file_with_sps_to_live_db.isAuthorized", paramMap);
return true;
}
}
calling all this from some action
examDAO = (ExaminationIfaceDAO)ApplicationInitializer.getApplicationContext().getBean("eexaminationIfaceDAO");
boolean b = reexamDAO.goToDW("myuserid");