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にジャンプします。なぜそれが起こるのか理解するのに苦労しています。で提供されたユーザー名とパスワードは正しいです。catchconnectionconnection.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

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

2 つの理由が考えられます。

  • dS.getConnection()例外をスローしています。catch ブロックはすべてをキャッチするため、例外になる可能性があります。ロールバックの時点にあるため、catch ブロックのNullPointerException 内部に入ります。connectionnull
  • dS.getConnection()をスローするnull原因となるa を返しています。これは、がviaに設定されているためです。connection.getAutoCommit()NullPointerExceptionconnectionnulldS.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()続行します。必要に応じてまたはを使用できます。connectionnullif (connection != null) { /* rest of code */ }if (connection == null) throw new NullPointerException();
于 2012-10-25T16:34:58.243 に答える
1

おそらく、接続が適切に作成されていないためです。connectionロールバックを実行する前に、が null でないかどうかを確認する必要があります。

また、少なくともエラーを記録する必要があります。そうすれば、何が起こっているのかを把握できます。

オブジェクトが null であると思われますdS。名前の不一致が原因で、適切に注入されなかった可能性があります。

于 2012-10-25T16:18:11.667 に答える
1

try ブロックから例外をログに記録してみてください。

ほとんどの場合、次の行で例外がスローされます: connection = dS.getConnection();

一般に、可能であれば、すべての例外をキャッチすることは避けるべきです。また、例外をログに記録して、何が起こっているかを把握します。名前が示すように、例外は望ましくないためです。

--tb

于 2012-10-25T16:21:19.013 に答える