Reputation: 1552
I'm new to Spring development.And right now,i'm really facing a problem.Here are the code snippets to make you realize my problem clearly.............
Here is my DAO class:
public class LoginDaoImpl {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public int checkLoginDetails(LoginVo loginVo){
String sql = "select count(*) from empsctygrp where username=? and password=?";
jdbcTemplate = new JdbcTemplate(dataSource);
int count = jdbcTemplate.queryForObject(sql,new Object[]{loginVo.getUserName(),loginVo.getPassword()},Integer.class);
return count;
}
}
Now here is my Business-Object(BO) class:
public class LoginBo {
LoginDaoImpl loginDaoImpl = new LoginDaoImpl();
public int checkLoginDetails(LoginVo loginVo){
return loginDaoImpl.checkLoginDetails(loginVo);
}
}
Now,here is my dispatcher-servlet xml code:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@117.194.83.9:1521:XE"/>
<property name="username" value="system"/>
<property name="password" value="password1$"/>
</bean>
<bean id="loginDaoImpl" class="com.abhinabyte.dao.LoginDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
Now whenever i'm trying to run this on server the following exception is given:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/A] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required] with root cause
java.lang.IllegalArgumentException: Property 'dataSource' is required
Please help me solve this problem.............:(
Upvotes: 1
Views: 10180
Reputation: 469
You should annotate that beans that will suffer IoC. Like
@Bean public class LoginDAOImpl { @Inject DataSource dataSource;......}
You set up in spring context this beans, but, you're not using them.
OBS:
When I use the JDBCTemplate I configure de IoC of JDBC like
<bean id="dataSourcePerfil" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${br.com.dao.jdbc.driver}" />
<property name="url" value="${br.com.dao.jdbc.url}" />
<property name="username" value="${br.com.dao.jdbc.user}" />
<property name="password" value="${br.com.dao.jdbc.pass}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSourcePerfil" />
</bean>
then.... after at all
@Bean
public class LoginDAOImpl {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<ClienteReport> getClientes() {
return Collections<ClienteReport>. emptyList();
}
}
Upvotes: 0
Reputation: 1473
I was having the same problem and could not find a comprehensive answer on the web, so I decided to post one here for anyone else, or for future me.
I'm still learning so if you think I have made a mistake below, please feel free to edit.
Summary:
<integration:annotation-config/> <context:component-scan base-package="myproject"/>
in your servlet to pick up annotations@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:WEB-INF/FinanceImportTool-servlet.xml")
dataSource
or jdbcTemplate
if these fields are already provided by a parent class e.g. StoredProcedure
new()
as this initializes classes outside the applicationContextMy original class (now altered):
public class MyDAOImpl extends StoredProcedure implements MyDAO {
private static final String SPROC_NAME = "dbo.MySP";
public MyDAOImpl(DataSource dataSource) {
super(dataSource, SPROC_NAME);
// ...declared parameters...
compile();
}
}
MyProject-servlet.xml file (only relevant bits included):
<!-- Used by Spring to pick up annotations -->
<integration:annotation-config/>
<context:component-scan base-package="myproject"/>
<bean id="MyDAOBean" class="myproject.dao.MyDAOImpl" >
<constructor-arg name="dataSource" ref="myDataSource"/>
</bean>
<!-- properties stored in a separate file -->
<bean id="myDataSource" class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
<property name="databaseName" value="${myDataSource.dbname}" />
<property name="serverName" value="${myDataSource.svrname}" />
<!-- also loaded portNumber, user, password, selectMethod -->
</bean>
Error: property 'dataSource' is required, or NullPointerException (1)
Other answers say make sure you have passed dataSource
as a <property>
for your bean in the servlet, etc.
I think @Abhinabyte the OP needed to annotate his setDataSource()
method with @Annotation
, and use <integration:annotation-config/> <context:component-scan base-package="myproject"/>
in his servlet to successfully pass in dataSource
as a dependency to LoginDaoImpl
.
In my case, I tried adding 'dataSource' as a property and autowiring it. The "dataSource is required" error message became a NullPointerException error.
I realised after far too long that MyDAOImpl
extends StoredProcedure
.
dataSource
was already a property of StoredProcedure
. By having a dataSource
property for MyDAOImpl
, the autowiring was not picking up and setting the dataSource
property of StoredProcedure
, which left dataSource
for StoredProcedure
as null.
This was not picked up when I tested the value of MyDAOImpl.dataSource
, as of course by now I had added a MyDAOImpl.dataSource field that had been autowired successfully. However the compile()
method inherited from StoredProcedure
used StoredProcedure.dataSource
.
Therefore I didn't need public DataSource dataSource;
property in MyDAOImpl
class. I just needed to use the StoredProcedure
constructor with super(dataSource, sql);
in the constructor for MyDAOImpl
.
I also didn't need a MyDAOImpl.jdbcTemplate
property. It was set automatically by using the StoredProcedure(dataSource, sql)
constructor.
Error: NullPointerException (2)
I had been using this constructor:
private static final String SPROC_NAME = "dbo.MySP";
public MyDAOImpl(DataSource dataSource) {
super(dataSource, SPROC_NAME);
}
This caused a NullPointerException
because SPROC_NAME
had not been initialized before it was used in the constructor (yes I know, rookie error). To solve this, I passed in sql
as a constructor-arg in the servlet.
Error: [same error message appeared when I had changed file name]
The applicationContext was referring to the bin/ instances of my beans and classes. I had to delete bin/ and rebuild the project.
My new class:
public class MyDAOImpl extends StoredProcedure implements MyDAO {
@Autowired // Necessary to prevent error 'no default constructor found'
public MyDAOImpl(DataSource dataSource, String sql) {
super(dataSource, sql);
// ...declared parameters...
compile();
}
New MyProject-servlet.xml file (only relevant bits included):
<!-- Used by Spring to pick up annotations -->
<integration:annotation-config/>
<context:component-scan base-package="myproject"/>
<bean id="myDAOBean" class="org.gosh.financeimport.dao.MyDAOImpl" >
<constructor-arg name="dataSource" ref="reDataSource"/>
<constructor-arg name="sql" value="dbo.MySP" />
</bean>
<!-- properties stored in a separate file -->
<bean id="myDataSource" class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
<property name="databaseName" value="${myDataSource.dbname}" />
<property name="serverName" value="${myDataSource.svrname}" />
<!-- also loaded portNumber, user, password, selectMethod -->
</bean>
Helpful places:
If you can get past the rage, this answer on Spring forums might help too
This answer gives a broad introduction to Spring configuration
This answer has simple but useful suggestions
Upvotes: 0
Reputation: 4513
Try this in LoginBo class:
@Autowired
LoginDaoImpl loginDaoImpl;
instead of
LoginDaoImpl loginDaoImpl = new LoginDaoImpl();
The problem is that you manually instantiate LoginDaoImpl.
Upvotes: 0