Hi and thanks for reading.
I'm having a problem trying to use a datasource defined in a config file which I've fondly named
applicationContext-jdbc.xml.
I'm referencing it in my web.xml. Here's the excerpt:
Code:
lt;context-paramgt; lt;param-namegt;contextConfigLocationlt;/param-namegt; lt;param-valuegt;/WEB-INF/applicationContext-jdbc.xmllt;/param-valuegt; lt;/context-paramgt;
Here's the applicationContext-jdbc.xml:
Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;beans xmlns=quot;schema/beansquot; xmlns:xsi=quot;2001/XMLSchema-instancequot; xsi:schemaLocation=quot;schema/beans schema/beans/spring-beans.xsdquot;gt; lt;bean id=quot;c3p0DataSourcequot; class=quot;com.mchange.v2.c3p0.mbean.C3P0PooledDataSourcequot;gt; lt;property name=quot;driverClassquot;gt;lt;valuegt;com.mysql.jdbc.Driverlt;/valuegt;lt;/propertygt; lt;property name=quot;jdbcuclquot;gt;lt;valuegt;jdbc:mysql--localhost:3306/ripitlt;/valuegt;lt;/propertygt; lt;property name=quot;userquot;gt;lt;valuegt;userlt;/valuegt;lt;/propertygt; lt;property name=quot;passwordquot;gt;lt;valuegt;loserlt;/valuegt;lt;/propertygt; lt;/beangt;
lt;!-- JNDI DataSource for J2EE environments May need this to lookup datasource --gt; lt;bean id=quot;jndiDataSourcequot; class=quot;org..jndi.JndiObjectFactoryBeanquot;gt; lt;property name=quot;jndiNamequot; value=quot;java:comp/env/jdbc/plusLinesquot;/gt; lt;/beangt;
lt;/beansgt;
This is where things get a little foggy for me...I am using the following in the class structure
somewhat refactored(hacked) from PetClinic..:
Code:
public class JdbcPolicy extends JdbcDaoSupport implements myInterface
{
public GetPolicySP getPolicySp;
private DataSource c3p0DataSource;
private static final String POLICY_INSURED_SQL = quot;slGetProducerquot;; //Stored Proc Name
private static Logger loggr = Logger.getLogger(JdbcPolicy.class.getName());
private int polNum;
public JdbcPolicy()
{
super();
// TODO Auto-generated constructor stub
}
public Map pSearch(String pNumber)
{
initDao(); //added this call when trying to solve Null Pointer dataSource Not Found...
loggr.info(quot;In JdbcPolicy:policySearch policy number= quot;+ pNumber);
return getPolicySp.execute(pNumber); //Was using this
}
/*this class was quite minimal, however the errors motivated me to throw
*the connection in here to get it working...and it does work, but not when trying to
* use the datasource configured in the xml file.... */
protected void initDao()
{
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(quot;com.mysql.jdbc.Driverquot;);
ds.setucl(quot;jdbc:mysql--localhost:3306/ripitquot;); ds.setUsername(quot;userquot;);
ds.setPassword(quot;loserquot;);
loggr.info(quot;Set up connection parametersquot;);
this.getPolicySp = new GetPolicySP(getDataSource());//this was where I tryed to get the dataSource...duh....
this.getPolicySp = new GetPolicySP(ds); //I put this together when the statement above started throwing the Null Pointers; local ds
}//subclass which executes sp this may be a sloppy practise using both StoredProcedure and JdbcDaoSupport together....
//don't really know at this point...
public class GetPolicySP extends StoredProcedure
{
private static final String SQL = quot;slnPolicyCountquot;;
private static final String POLICY_NUMBER = quot;policyNumberquot;;
public GetPolicySP(DataSource ds)
{
setDataSource(ds);
if(ds==null){loggr.info(quot;DataSource is nullquot;);} //debug which helped me figure out the ds was null, even though examples seem to work
setFunction(false);
setSql(SQL);
loggr.info(quot;set sql parametersquot;);
declareParameter(new SqlParameter(POLICY_NUMBER, Types.VARCHAR));
declareParameter(new SqlOutParameter(quot;pcountquot;, Types.INTEGER));
loggr.info(quot;Set parameters for Stored Procedurequot;);
compile();
}
public Map execute(String pNumber)
{
HashMap inputs = new HashMap();
loggr.info(quot;In execute; inputs are quot; + POLICY_NUMBER + quot; and quot; + pNumber);
inputs.put(POLICY_NUMBER, pNumber);
return super.execute(inputs);
}}
}
When I use the xml defined dataSource I receive a Null Pointer, and verbage that Datasource not found.
When I use the local ds, this guy runs....Any ideas, because it appears most of the other posters don't
experience this problem...
I will replacing mySql with Oracle in the next week or so, which should be a non-issue...
Thanks,
Peter Adelmann
Do you inject the datasource into your dao?
Marten,
I'm still working on the inject concept. By what you said, do you mean
performing a setDataSource(ds) , or something like that?
Peter
Hi u812b4me,
I think what mdeinum is saying is that your JdbcPolicy expects a DataSource implementation bean. So, have you configured a JdbcPolicy bean in your applicationContext-jdbc.xml? If not, you need to. You also need to be sure that you inject the c3p0DataSource bean into the JdbcPolicy bean.
The fact that you are not receiving an IllegalArgumentException with a quot;dataSource or jdbcTemplate is requiredquot; message makes me think that you are not obtaining the JdbcPolicy class from the Spring BeanFactory, but are instead instantiating it yourself. If so, this is effectively bypassing Spring.
Here is my suggested applicationContext-jdbc.xml:
Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;beans xmlns=quot;schema/beansquot; xmlns:xsi=quot;2001/XMLSchema-instancequot; xsi:schemaLocation=quot;schema/beans schema/beans/spring-beans.xsdquot;gt; lt;bean id=quot;c3p0DataSourcequot; class=quot;com.mchange.v2.c3p0.mbean.C3P0PooledDataSourcequot;gt; lt;property name=quot;driverClassquot;gt;lt;valuegt;com.mysql.jdbc.Driverlt;/valuegt;lt;/propertygt; lt;property name=quot;jdbcuclquot;gt;lt;valuegt;jdbc:mysql--localhost:3306/ripitlt;/valuegt;lt;/propertygt; lt;property name=quot;userquot;gt;lt;valuegt;userlt;/valuegt;lt;/propertygt; lt;property name=quot;passwordquot;gt;lt;valuegt;loserlt;/valuegt;lt;/propertygt; lt;/beangt;
lt;!-- JNDI DataSource for J2EE environments May need this to lookup datasource --gt; lt;bean id=quot;jndiDataSourcequot; class=quot;org..jndi.JndiObjectFactoryBeanquot;gt; lt;property name=quot;jndiNamequot; value=quot;java:comp/env/jdbc/plusLinesquot;/gt; lt;/beangt;
lt;bean id=quot;myInterfacequot; class=quot;some.package.JdbcPolicyquot;gt; lt;property name=quot;dataSourcequot; ref=quot;c3p0DataSourcequot;/gt; lt;/beangt;
lt;/beansgt;
Now, if you obtain the quot;myInterfacequot; bean from a BeanFactory (getBean(quot;myInterfacequot;)), you will have an instance of your JdbcPolicy class with the correct DataSource.
You are correct about Spring's invoking the setDataSource(DataSource) method, but this cannot be done unless you configure the applicationContext correctly and you obtain the bean from the Spring BeanFactory.
Hope this helps!
-Arthur Loder
Arthur,
I think I get it now. 1000 Thank You's!!!
Peter
I'm still in conundrum concerning this
Arthur mentioned something which has me baffled and I'm hoping someone can show an example...
quot;Now, if you obtain the quot;myInterfacequot; bean from a BeanFactory (getBean(quot;myInterfacequot;)), you will have an instance of your JdbcPolicy class with the correct DataSource.
You are correct about Spring's invoking the setDataSource(DataSource) method, but this cannot be done unless you configure the applicationContext correctly and you obtain the bean from the Spring BeanFactory.quot;I really don't understand this. Could someone please sketch out an example based on the applicationContext-jdbc.xml above?
I've spent all day on this, and am chasing my tail at this point...Peter
Hi Peter,
Here is some sample code that reads the applicationContext-jdbc.xml file, obtains the quot;myInterfacequot; bean (which is really a properly configured JdbcPolicy instance), and performs an operation on the bean:Code:
package org.spring.forum;
import org..context.ApplicationContext;
import org..context.support.ClassPathXmlApplicationContext;
public class SampleReadingContext {
public static void main(String[] args) { //Read the applicationContext file, a subclass of BeanFactory ApplicationContext ctx = new ClassPathXmlApplicationContext(quot;applicationContext-jdbc.xmlquot;); /* * Obtain the 'myInterface' bean from Spring; Spring will return a * configured JdbcPolicy class with the proper DataSource */ MyInterface myInterface = (MyInterface)ctx.getBean(quot;myInterfacequot;); /* * From here, perform operations defined on the MyInterface interface; I * assume that the pSearch method is defined in MyInterface. */ myInterface.pSearch(quot;someStringquot;); }
}
There are other issues to consider, such as how/where to read in the context, and there are many posts considering those issues. However, the sample code above gives you an overview.
Remember: if you yourself instantiate (via the 'new' operator) the JdbcPolicy class, Spring will not be involved at all, so the DataSource implementation will not be set. You could programmatically instantiate the JdbcPolicy class, instantiate the DataSource, and then call setDataSource() method on the JdbcPolicy class. But the beauty of Spring is that it will handle all of this for you if you set up your context file correctly and are sure to always obtain your beans from Spring (either through dependency injection or via an explicit getBean() call to a Spring BeanFactory).
Hope this helps! Let me know if you have any other questions or this is not clear.
-Arthur Loder
Arthur,
You are a huge help in clarification.
I understand the applicationContext and thought it would be automatically created when the application starts. However, I do have another application-Context.xml file which defines a domain object called a Policy. I was using this to deposit the results of a Stored Procedure call retrieving the details.
My nose bleed level thought was that the jdbc would be more of a service based on the input supplied from the controller. The controller would pass a message back to the jdbc service telling it to go retrieve data, populate a domain object and return it to the controller. However in the process of constructing all of this as a prototype, things got a little muddy and the separation of concerns become tainted. So now I'm not really sure what my jdbc service is doing, because it's mutated into a bean, and my domain object has become an overflow of the service which might actually be okay...
Also, the Web Flow concept looks very interesting because the application
I trying to create definately has a couple of flows associated with it(Another question, could a flow roughly be interpreted as a Use Case?).
I guess I ranted there; I've still got a ways to go, and not much time to do it.
Thank you for your assistence, and feel free to comment/question/pull apart any part of the aforementioned rumination.
Peter |