有人可以告诉我如何修复下面的代码,以免它引发错误吗?
以下代码行给出了一个空指针异常:
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>
答案 0 :(得分:1)
我怀疑它“运行良好”的代码是实际在应用服务器中运行的代码。您要发布的示例(仅运行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/
答案 1 :(得分:1)
将dataSource用作<javax.sql.DataSource>
个实例,而不是<javax.activation.DataSource>
的实例。
简而言之,您应该用另一个<import javax.activation.DataSource;>
替换语句<import javax.sql.DataSource;>
。
答案 2 :(得分:1)
使用dataSource作为javax.sql.DataSource实例,而不是javax.activation.DataSource的实例。简而言之,您应该替换声明:
import javax.activation.DataSource;
由另一个人:
import javax.sql.DataSource;