I am trying to learn the Spring framework. I am making a simple test application. I have a Client that calls Service that calls a DAO.
The Client calls the Service like this:
XML
<bean id="myService" class="test.package.service.MyServiceImpl">
<property name="indexFilePath" value="${indexFilePath}" />
<property name="pdfFilePath" value="${pdfFilePath}" />
</bean>
Java
public static void main(String[] args)
{
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = (MyService)context.getBean("myService");
myService.doStuff();
context.close();
}
I want the Service to call the DAO:
XML
<bean id="trackingDAO" class="test.package.dataaccess.TrackingDAOImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${trackingDb.driver}" />
<property name="url" value="${trackingDb.url}" />
<property name="username" value="${trackingDb.username}" />
<property name="password" value="${trackingDb.password}" />
</bean>
My problem is that I have both of these XML pieces in the same file. So I do not know how to access the DAO bean. I do not believe I can open the same context when it is still open in "main". Should I create a second context file? If so, what is a food rule of thumb for when I should create a new context file? I do not like the idea of have many of these. Or perhaps the DAO should be a property of the Service?
<bean id="myService" class="test.package.service.MyServiceImpl">
<property name="indexFilePath" value="${indexFilePath}" />
<property name="pdfFilePath" value="${pdfFilePath}" />
<property name="dao" ref="trackingDAO" />
</bean>
Within your service, add a property of dao, like you mentioned.
public class MyServiceImpl {
....
TrackingDAO dao; //assuming thats the interface , or use Impl.
....
}
Year! U are right "the DAO should be a property of the Service"!
and the piece just need one in U Spring contxt xml file!
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${trackingDb.driver}" />
<property name="url" value="${trackingDb.url}" />
<property name="username" value="${trackingDb.username}" />
<property name="password" value="${trackingDb.password}" />
</bean>
this piece just need one in U Spring contxt xml file!
Try ! it's will work well!
Related
I am using spring 3 but my configuration is xml based in which I am trying to convert my project into annotation based using #configuration annotation.
I am little confused how to add data source entry as #Bean for two below cases
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/myds" />
</bean>
<bean id="data_source" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="url1" />
<property name="username" value="user1" />
<property name="password" value="****" />
</bean>
I am running a spring application with xml configuration. I have defined two beans in the application-configuration.xml followed as
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="myDataSource"></property>
</bean>
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
and I am trying to get the bean simply as
public class SQLDbService {
#Autowired
JdbcTemplate jdbcTemplate;
public void someMethod()
{
jdbcTemplate.execute();
}
}
but the jdbcTemplate field is always null.
The application starts from another class
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-configuration.xml");
}
I tried adding
<context:annotation-config/>
to application configuration.
I would like to know if an annotation-based autowiring is possible at this point, if so, what I am missing?
<bean id="sQLDbService" class="path.to.your.package.SQLDbService">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
In the Java Spring bean configuration of dataSrouce, I tried to define init and destroy attributes which call my mysql scripts as initialization and cleanup for unit tests, as the code shown below:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="destroy" init-method="init">
<property name="destroy">
<value>classpath: mysql_dropuser.sql</value>
</property>
<property name="init">
<value>classpath: mysql_createuser.sql,classpath: mysql_bootstrap.sql</value>
</property>
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8" />
</bean>
But I got the error:
Invalid property 'destroy' of bean class.
My question is that how I could define the init and destroy methods in the xml file?
This is how I did it once before, hope this helps:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<property name="username" value="testuser" />
<property name="password" value="testuser" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
<property name="maxIdle" value="20" />
<property name="maxWait" value="5000" />
</bean>
<jdbc:initialize-database data-source="dataSource" ignore-failures="ALL">
<jdbc:script execution="INIT" location="classpath:database/schemas/create_testdb.sql" />
<jdbc:script execution="INIT" location="classpath:database/schemas/add_testdata.sql" />
<jdbc:script execution="DESTROY" location="classpath:database/schemas/drop_testdb.sql" />
</jdbc:initialize-database>
It seems like you have already defined init/destroy methods (they are specified via corresponding attributes). And you should also have public void no-argument methods with that names in your class. Properties are a bit different; as usual they are considered as combination of private field and public get/set methods. So in your case at least setter method public void setDestroy(String str) is expected. Please, check your bean's class to meet these conventions. You may also look for 'spring resource' (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html) injection, since you're trying to provide file paths into you bean.
in my applicationcontext.xml i have this :
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dashboardsupervisor" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
here i am connecting with my database :
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MySQLRdbHelper rdbHelper = (MySQLRdbHelper)
ctx.getBean("ManagerSupervisor");
What is want is to NOT read the password "1234" from my applicationcontext.xml
and read it from some properties file in my local drive .
as this will be running on different machines and every one have different passwords.
Can i achieve this .
thanks
Yes, you can, and the key to this is Springs PropertyPlaceholderConfigurer.
For example, you create a file on your file system called database.properties, containing your password (note, that you can also add more settings to this file, like username, JDBC url, etc).
jdbc.password=1234
Next, you need to declare a PropertyPlaceholderConfigurer bean and point it to the database.properties file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>path/to/database.properties</value>
</property>
</bean>
Note that the path is interpreted as a classpath resource, unless it is prefixed with file:.
Finally, replace the configuration of your dataSource bean: replace
<property name="password" value="1234" />
with
<property name="password" value="${jdbc.password}" />
You could use profiles:
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev1");
ctx.load("*Context.xml");
ctx.refresh();
<bean id="database1" profile="dev1"/>
<bean id="database2" profile="dev2">
The best way is to create the data source in application server and configure as below in application.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>YourDSName</value></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
.....
</bean>
I'm trying to use TopLink with Spring but I'm having a problem. I'm using it in a webservice (CXF).
When I use getTopLinkTemplate(), the resul is null.
Here is my applicationContext.xml :
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#*************" />
<property name="username" value="*****" />
<property name="password" value="*****" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.toplink.LocalSessionFactoryBean">
<property name="configLocation" value="toplink-sessions.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="myProductDao" class="ToplinkExecPS.ExecPS">
<property name="sessionFactory">
<ref local="mySessionFactory" />
</property>
</bean>
My code is :
public class ExecPS extends TopLinkDaoSupport{
public Vector Exec(String test)
{
TopLinkTemplate t;
t = getTopLinkTemplate();
if (t == null)
System.out.println("template is null");
}
}
So, when I execute this code, I have "template is null" in the console and a nullPointerException when I try to use the variable "t".
For information, the connection to the database with TopLink is successful.
[TopLink - Infos] : 2012.05.23 03:45:22.113--ServerSession(4812898)--Thread(Thread[main,5,main])--Session - connexion réussie
I have testing so many things and I'm still stuck. I hope you will help me.
[EDIT]
OK I'm really a noob. I just forget to get my bean before call the method...
If anyone get on this thread, there is the code:
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(new String[]{"ToplinkContext.xml"} );
ExecPS exec = (ExecPS)context.getBean("myProductDao");
Not 100% on this one but I would be suspicious of this line:
<property name="configLocation" value="toplink-sessions.xml" />
Unsure toplink-sessions.xml is on your classpath and try the following:
<property name="configLocation" value="classpath:toplink-sessions.xml" />