运行项目会抛出此错误:
java.lang.NullPointerException
com.myproject.crud.EmployeesJDBCImpl.withDB(EmployeesJDBCImpl.java:157)
com.myproject.crud.EmployeesJDBCImpl.doList(EmployeesJDBCImpl.java:119)
com.myproject.crud.EmployeesJDBCImpl.listEmployees(EmployeesJDBCImpl.java:111)
com.myproject.crud.EmployeesJDBCImpl$Proxy$_$$_WeldClientProxy.listEmployees(EmployeesJDBCImpl$Proxy$_$$_WeldClientProxy.java)
com.myproject.crud.EmployeesListServlet.doGet(EmployeesListServlet.java:36)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
try
块失败并跳转到catch
块,connection
对象在调用connection.rollback()
时似乎为空。很难理解为什么会发生这种情况。 context.xml
中提供的用户名和密码是正确的。
EmployeesJDBCImpl.java
package com.myproject.crud;
import java.util.ArrayList;
import java.util.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.enterprise.context.ApplicationScoped;
import javax.annotation.Resource;
import javax.sql.DataSource;
@ApplicationScoped @JDBC
public class EmployeesJDBCImpl implements EmployeesRepository {
@Resource(name="jdbc/EmployeesDB")
private DataSource dS;
@Override
public Employee viewEmployee(final String id) {
return withDB(new JDBCRunner<Employee>(){
@Override
public Employee run(Connection connection) throws Exception{
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM employees WHERE id = ?");
preparedStatement.setString(1, id);
ResultSet rs = preparedStatement.executeQuery();
if(rs.next()){
Employee employee = new Employee();
employee.setId(rs.getString("id"));
employee.setName(rs.getString("name"));
employee.setPhone(rs.getString("phone"));
employee.setEmail(rs.getString("email"));
return employee;
}else{
return null;
}
}});
}
private <T> T withDB(JDBCRunner<T> runner){
Connection connection = null;
try{
connection = dS.getConnection();
boolean auto = connection.getAutoCommit();
connection.setAutoCommit(false);
T result = runner.run(connection);
connection.commit();
connection.setAutoCommit(auto);
return result;
}catch(Exception e){
try{
connection.rollback(); // Nullpointer exception here
}catch(SQLException ex){
}
//throw new EmployeesException(e);
}finally{
if(connection != null){
try{
connection.close();
}catch(Exception ex){
}
}
}
return null;
}
}
META-INF / context.xml中
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/EmployeesDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="root" password="secret" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
WEB-INF / web.xml中
...
<description>MySQL Employees App</description>
<resource-ref>
<description>db connection</description>
<res-ref-name>jdbc/EmployeesDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
...
答案 0 :(得分:1)
可能是因为您的连接未正确创建。在执行回滚之前,您应该检查connection
是否为空。
此外,您应该至少记录错误,这样您就可以了解正在发生的事情。
我怀疑你的dS
对象为空,可能由于名称不匹配而没有正确注入。
答案 1 :(得分:1)
尝试从try块中记录异常。
最有可能的是,这一行会抛出异常: connection = dS.getConnection();
一般情况下,如果可能,应避免捕获所有异常。并记录异常,以便您知道发生了什么。因为例外,如名称所示,不需要。
- TB
答案 2 :(得分:1)
我无法看到您初始化DataSource的位置
connection = dS.getConnection();
你必须有一些dS的查找代码
类似于:
Context ctx=new InitialContext();
DataSource dS=(DataSource)ctx.lookup("jdbc/sampledb");
Connection con=dS.getConnection();
答案 3 :(得分:1)
有两个可能的原因:
dS.getConnection()
正在抛出异常。可以是任何异常,因为你的catch块会捕获所有内容。您在 catch块中获得NullPointerException
,因为connection
在回滚时为null
。dS.getConnection()
返回null
,导致connection.getAutoCommit()
抛出NullPointerException
。这是因为connection
已通过null
设置为dS.getConnection()
。在你的catch区块中,从e.printStackTrace()
开始,找出真正的问题:
...
}catch(Exception e){
e.printStackTrace(); //This should show you what the real problem is
try{
connection.rollback();
}catch(SQLException ex){
}
//throw new EmployeesException(e);
}finally{
...
<强>解决方案:强>
connection
是否不是null
。如果从未创建数据库连接,则不必回滚它。 我每天都会在大型项目中处理这种设置,这就是我们的工作。 dS.getConnection()
后,如果connection
不是null
,请继续 。您可以根据需要使用if (connection != null) { /* rest of code */ }
或if (connection == null) throw new NullPointerException();
。