繁体   English   中英

javax.sql.datasource getconnection返回null

[英]javax.sql.datasource getconnection returns null

有人可以告诉我如何修复下面的代码,以便它不会抛出错误?

以下代码行给出了一个空指针异常:

return dataSource.getConnection();

请注意,dataSource是javax.sql.DataSource的一个实例,它在web.xml中指定,并且在被其他代码调用时工作正常。

以下是DataAccessObject.java中发生空指针的实际方法:

protected static Connection getConnection(){  
  try {
     return dataSource.getConnection();  //
  } catch (SQLException e) {
     throw new RuntimeException(e);
  }
}

这行代码调用上述方法:

connection = getConnection();  

它位于以下方法中,名为CourseSummaryDAO,如下所示:

public List<CourseSummary> findAll(Long sid) {
    LinkedList<CourseSummary> coursesummaries = new LinkedList<CourseSummary>();
    ResultSet rs = null;
    PreparedStatement statement = null;
    Connection connection = null;
    try {
        connection = getConnection(); //
        String sql = "select * from coursetotals where spid=?";
        statement = connection.prepareStatement(sql);
        statement.setLong(1, sid);
        rs = statement.executeQuery();
        //for every row, call read method to extract column 
        //values and place them in a coursesummary instance
        while (rs.next()) {
            CourseSummary coursesummary = read("findAll", rs);
            coursesummaries.add(coursesummary);
        }
        return coursesummaries;
     }catch (SQLException e) {
        throw new RuntimeException(e);
     } 
     finally {
        close(rs, statement, connection);
    }
 }  

为了简单地重新创建这个,我创建了以下TestCourseSummaries类:

public class TestCourseSummaries {
    public static void main(String[] args) {
    Long id = new Long(1002);
    CourseSummaryDAO myCSDAO = new CourseSummaryDAO();
    List<CourseSummary> coursesummaries = myCSDAO.findAll(id);
    for(int i = 0;i<coursesummaries.size();i++){
    System.out.println("type, numunits are: "+coursesummaries.get(i).getCourseType()+","+coursesummaries.get(i).getNumUnits());
    }
}
}  

编辑:

为了解决JustDanyul的问题,我附上了在我的应用程序中调用的代码,以及由调用代码中的两个DAO对象扩展的基础DataAccessObject代码:

以下是我的应用程序中触发错误的代码。 看每个扩展DataAccessObject有两个类。 也许它们彼此冲突,导致第二个不能获得数据库连接?

protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {  
   String idString = req.getParameter("id");
   Long id = new Long(idString);
   ThisObj thisobj = new ThisDAO().find(id);
   req.setAttribute("thisobj", thisobj);
   ThoseObjDAO myThoseDAO = new ThoseObjDAO();
   List<ThoseObj> thoseobjects = myThoseObjDAO.findAll(id);
   req.setAttribute("thoseobjects", thoseobjects);
   jsp.forward(req, resp);

}

这是DataAccessObject类的代码,它由调用代码中的两个DAO类扩展:

public class DataAccessObject {
private static DataSource dataSource;
private static Object idLock = new Object();

public static void setDataSource(DataSource dataSource) {
   DataAccessObject.dataSource = dataSource;
}

protected static Connection getConnection() {
   try {return dataSource.getConnection();}
   catch (SQLException e) {throw new RuntimeException(e);}
}

protected static void close(Statement statement, Connection connection) {
   close(null, statement, connection);
}

protected static void close(ResultSet rs, Statement statement, Connection connection) {
   try {
      if (rs != null) rs.close();
      if (statement != null) statement.close();
      if (connection != null) connection.close();
   } catch (SQLException e) {throw new RuntimeException(e);}
}

protected static Long getUniqueId() {
   ResultSet rs = null;
   PreparedStatement statement = null;
   Connection connection = null;
   try {
      connection = getConnection();
      synchronized (idLock) {
         statement = connection.prepareStatement("select next_value from sequence");
         rs = statement.executeQuery();
         rs.first();
         long id = rs.getLong(1);
         statement.close();
         statement = connection.prepareStatement("update sequence set next_value = ?");
         statement.setLong(1, id + 1);
         statement.executeUpdate();
         statement.close();
         return new Long(id);
      }
   }
   catch (SQLException e) {throw new RuntimeException(e);}
   finally{close(rs, statement, connection);}
}
}  

数据源在web.xml中创建,如下所示:

<resource-ref>
    <description>dataSource</description>
    <res-ref-name>datasource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

我怀疑它“运行良好”的代码是实际在应用程序服务器中运行的代码。 您要发布的示例(仅运行static void main()方法)将不会获取已在web.xml中定义的任何资源。

我猜你使用JDNI来设置初始数据源。 然后用类似的东西

@Resource(name="jdbc/mydb")
private DataSource dataSource;

设置您的连接。 对?

编辑:

在看到您的代码后,您的数据源似乎是初始化的。 只是将一个元素放入web.xml就不会单独完成。 你还需要实际配置dataSource,你知道,指定驱动程序,用户名,密码,uri等等。

我猜测DAO的find()方法有效,实际上并没有使用dataSource。 到目前为止你所展示的内容并没有说明你有一个初始化的dataSource。

为了给你一个想法,我喜欢有关如何使用Tomcat和JDNI执行此操作的教程。 (或者甚至更好,使用spring-jdbc)。

http://www.mkyong.com/tomcat/how-to-configure-mysql-datasource-in-tomcat-6/

使用dataSource作为<javax.sql.DataSource>实例,而不是<javax.activation.DataSource>的实例。

简而言之,您应该用另一个<import javax.sql.DataSource;>替换语句<import javax.activation.DataSource;> <import javax.sql.DataSource;>

使用dataSource作为javax.sql.DataSource实例,而不是javax.activation.DataSource的实例。 简而言之,您应该替换声明:

import javax.activation.DataSource; 

由另一个:

import javax.sql.DataSource;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM