Spring 3 MVC:java.lang.IllegalArgumentException:需要属性“dataSource”。如何正确设置JdbcTemplate?

问题描述 投票:0回答:3

我是 Spring 开发的新手。现在,我真的面临一个问题。以下是代码片段,可以让您清楚地认识到我的问题........................

这是我的 DAO 课程:

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;
    }   
}

现在这是我的业务对象(BO)类:

public class LoginBo {

    LoginDaoImpl loginDaoImpl = new LoginDaoImpl();

    public int checkLoginDetails(LoginVo loginVo){      
        return loginDaoImpl.checkLoginDetails(loginVo);
    }
}

现在,这是我的调度程序 servlet xml 代码:

<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>

现在,每当我尝试在服务器上运行它时,都会出现以下异常:

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:需要属性“dataSource”


请帮我解决这个问题........................:(

spring model-view-controller spring-3 spring-jdbc jdbctemplate
3个回答
0
投票

在 LoginBo 类中尝试一下:

@Autowired
LoginDaoImpl loginDaoImpl;

而不是

LoginDaoImpl loginDaoImpl = new LoginDaoImpl();

问题是你手动实例化LoginDaoImpl。


0
投票

我遇到了同样的问题,并且无法在网络上找到全面的答案,因此我决定在这里为其他人或未来的我发布一个答案。

我仍在学习,所以如果您认为我在下面犯了错误,请随时编辑。

总结:

  • 在 servlet 中包含
    <integration:annotation-config/> <context:component-scan base-package="myproject"/>
    以获取注释
  • 使用
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("file:WEB-INF/FinanceImportTool-servlet.xml")
  • 配置 JUnit 测试
  • 如果父类已经提供了这些字段,则不要自动装配
    dataSource
    jdbcTemplate
    ,例如
    StoredProcedure
  • 不要使用
    new()
    ,因为这会初始化 applicationContext 之外的类
  • 谨防在构造函数中使用尚未设置的属性 - 显而易见但非常容易做到

我原来的班级(现已更改):

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 文件(仅包含相关位):

<!-- 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>

错误:需要属性“dataSource”,或 NullPointerException (1)

其他答案说确保您已通过

dataSource
作为 servlet 中的 bean 的
<property>
等。

我认为@Abhinabyte OP需要用

setDataSource()
注释他的
@Annotation
方法,并在他的servlet中使用
<integration:annotation-config/> <context:component-scan base-package="myproject"/>
才能成功地将
dataSource
作为对
LoginDaoImpl
的依赖项传递。

就我而言,我尝试添加“dataSource”作为属性并自动装配它。 “需要数据源”错误消息变成了 NullPointerException 错误。

过了太久我才意识到

MyDAOImpl
延伸了
StoredProcedure

dataSource
已经是
StoredProcedure
的属性。通过为
dataSource
设置
MyDAOImpl
属性,自动装配不会拾取并设置
dataSource
StoredProcedure
属性,从而使
dataSource
StoredProcedure
为空。

当我测试

MyDAOImpl.dataSource
的值时,没有发现这一点,因为现在我当然已经添加了一个已成功自动连接的 MyDAOImpl.dataSource 字段。然而,从
compile()
继承的
StoredProcedure
方法使用了
StoredProcedure.dataSource

因此我不需要

public DataSource dataSource;
类中的
MyDAOImpl
属性。我只需要在
StoredProcedure
的构造函数中使用
super(dataSource, sql);
构造函数和
MyDAOImpl

我也不需要

MyDAOImpl.jdbcTemplate
财产。它是通过使用
StoredProcedure(dataSource, sql)
构造函数自动设置的。


错误:NullPointerException (2)

我一直在使用这个构造函数:

private static final String SPROC_NAME = "dbo.MySP";

public MyDAOImpl(DataSource dataSource) {
    super(dataSource, SPROC_NAME);
}

这导致了

NullPointerException
,因为
SPROC_NAME
在构造函数中使用之前尚未初始化(是的,我知道,菜鸟错误)。为了解决这个问题,我在 servlet 中传入
sql
作为构造函数参数。


错误:[更改文件名时出现相同的错误消息]

applicationContext 指的是我的 bean 和类的 bin/ 实例。我必须删除 bin/ 并重建项目。


我的新班级:

   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();
   }

新的 MyProject-servlet.xml 文件(仅包含相关部分):

<!-- 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>

有用的地方:

如果你能平息愤怒,Spring 论坛上的这个答案也可能有帮助

这个答案对Spring配置进行了广泛的介绍

这个答案有简单但有用的建议


0
投票

您应该注释那些将遭受 IoC 影响的 Bean。喜欢

@Bean public class LoginDAOImpl { @Inject DataSource dataSource;......}

您在 spring 上下文中设置了这个 bean,但是,您没有使用它们。

OBS:

当我使用 JDBCTemplate 时,我会像

那样配置 JDBC 的 IoC
<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>

然后....毕竟

@Bean

公共类LoginDAOImpl {

@Autowired
private JdbcTemplate jdbcTemplate;


@Override
public List<ClienteReport> getClientes() {
    return Collections<ClienteReport>. emptyList();
}

}

© www.soinside.com 2019 - 2024. All rights reserved.