javax.sql.datasource getconnection 返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18157290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javax.sql.datasource getconnection returns null
提问by CodeMed
Can someone please show me how to fix the code below so that it does not throw an error?
有人可以告诉我如何修复下面的代码以使其不会引发错误吗?
The following line of code is giving me a null pointer exception:
以下代码行给了我一个空指针异常:
return dataSource.getConnection();
Note that dataSource is an instance of javax.sql.DataSource which is specified in web.xml, and which works fine when called by other code.
请注意,dataSource 是在 web.xml 中指定的 javax.sql.DataSource 的一个实例,当被其他代码调用时它可以正常工作。
Here is the actual method in DataAccessObject.java where the null pointer is occurring:
这是 DataAccessObject.java 中出现空指针的实际方法:
protected static Connection getConnection(){
try {
return dataSource.getConnection(); //
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
The preceding method is being called by this line of code:
这行代码正在调用前面的方法:
connection = getConnection();
Which is located in the following method in a class called CourseSummaryDAO as follows:
它位于名为 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);
}
}
To recreate this simply, I created the following TestCourseSummaries class:
为了简单地重新创建它,我创建了以下 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());
}
}
}
EDIT:
编辑:
To address JustDanyul's question, I am enclosing the code that calls in my application, and the underlying DataAccessObject code which is extended by the two DAO objects in the calling code:
为了解决 JustDanyul 的问题,我附上了在我的应用程序中调用的代码,以及由调用代码中的两个 DAO 对象扩展的底层 DataAccessObject 代码:
Here is the code in my application which triggers the error. See there are two classes that each extended DataAccessObject. Perhaps they are conflicting with each other, causing the second one not to get the database connection?
这是我的应用程序中触发错误的代码。看到有两个类,每个类都扩展了 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);
}
}
And here is the code for the DataAccessObject class which is extended by the two DAO classes in the calling code:
这是 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);}
}
}
The data source is created in web.xml, as follows:
数据源在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>
采纳答案by JustDanyul
I suspect that the code where it "runs fine" in, is code actually running in an application server. The example you are posting, which just runs a static void main()
method, wont get any resources which has been defined in web.xml.
我怀疑它“运行良好”的代码实际上是在应用程序服务器中运行的代码。您发布的示例仅运行一个static void main()
方法,不会获取已在 web.xml 中定义的任何资源。
I am guessing that you use JDNI to setup the initial datasource. And then using something like
我猜您使用 JDNI 来设置初始数据源。然后使用类似的东西
@Resource(name="jdbc/mydb")
private DataSource dataSource;
to set up your connection. Right?
设置您的连接。对?
EDIT:
编辑:
After seeing your code, it seems like your data source is newer initialised at all. Just putting a element into your web.xml will not do it alone. You will also need to actually configure the dataSource, you know, specify the driver, username, password, uri etc etc etc.
看到您的代码后,您的数据源似乎是新初始化的。仅仅将一个元素放入您的 web.xml 不会单独完成。您还需要实际配置数据源,您知道,指定驱动程序、用户名、密码、uri 等等等。
I'm guessing the find() method of the DAO that works, isn't actually using the dataSource. What you have shown so far, doesn't insigunate that your have a initialised dataSource at all.
我猜测有效的 DAO 的 find() 方法实际上并未使用数据源。到目前为止,您所展示的内容并没有暗示您有一个初始化的数据源。
Just to give you an idea, I liked a tutorial on how you would do this with Tomcat and JDNI. (Or even better, use spring-jdbc).
只是为了给您一个想法,我喜欢有关如何使用 Tomcat 和 JDNI 执行此操作的教程。(或者甚至更好,使用 spring-jdbc)。
http://www.mkyong.com/tomcat/how-to-configure-mysql-datasource-in-tomcat-6/
http://www.mkyong.com/tomcat/how-to-configure-mysql-datasource-in-tomcat-6/
回答by GuillermoEstevez
Use dataSource as <javax.sql.DataSource>
instance, rather than an instance of <javax.activation.DataSource>
.
使用 dataSource 作为<javax.sql.DataSource>
实例,而不是<javax.activation.DataSource>
.
In short, you should replace the statement <import javax.activation.DataSource;>
by this other <import javax.sql.DataSource;>
.
简而言之,您应该用<import javax.activation.DataSource;>
这个 other替换该语句<import javax.sql.DataSource;>
。
回答by GuillermoEstevez
Use dataSource as javax.sql.DataSource instance, rather than an instance of javax.activation.DataSource. In short, you should replace the statement:
使用 dataSource 作为 javax.sql.DataSource 实例,而不是 javax.activation.DataSource 的实例。简而言之,您应该替换以下语句:
import javax.activation.DataSource;
by this other:
通过这个其他:
import javax.sql.DataSource;