0

运行项目会抛出这个错误:

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正确。

雇员JDBCImpl.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>
...
4

4 回答 4

1

两个可能的原因:

  • dS.getConnection()正在引发异常。可以是任何例外,因为您的 catch 块捕获了所有内容。你NullPointerException 进入了 catch 块,因为connection它正null处于回滚点。
  • dS.getConnection()正在返回null导致connection.getAutoCommit()抛出 a 的 a NullPointerException。这是因为connection已设置为nullvia 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{
    ...

解决方案:

  • 在 catch 块中,在回滚之前检查是否connection不是。null如果从未创建数据库连接,则不必回滚。我每天在大型项目中处理这种设置,这就是我们所做的。
  • 次优解决方案:一旦dS.getConnection()完成,connectionis not时才继续null。您可以使用if (connection != null) { /* rest of code */ }if (connection == null) throw new NullPointerException();根据您的需要。
于 2012-10-25T16:34:58.243 回答
1

我看不到您在哪里初始化了 DataSource

 connection = dS.getConnection();

您必须有一些 dS 的查找代码

类似于:

Context ctx=new InitialContext();                        
DataSource dS=(DataSource)ctx.lookup("jdbc/sampledb");   
Connection con=dS.getConnection(); 
于 2012-10-25T16:24:53.963 回答
1

可能是因为您的连接没有正确创建。您应该connection在执行回滚之前检查是否不为空。

此外,您至少应该记录错误,这样您就能够弄清楚发生了什么。

我怀疑您的dS对象为空,可能由于名称不匹配而未正确注入。

于 2012-10-25T16:18:11.667 回答
1

尝试从 try 块记录异常。

最有可能的是,这行代码会抛出异常:connection = dS.getConnection();

一般来说,如果可能,您应该避免捕获所有异常。并记录异常,以便您了解发生了什么。因为正如名字所暗示的那样,例外是不想要的。

--待定

于 2012-10-25T16:21:19.013 回答