尝试将查询的结果集放入映射时抛出意外的NPE

时间:2016-11-03 04:28:12

标签: java mysql nullpointerexception hashmap

当我将结果集中的值放入地图时,我在以下代码中显示的行中得到Null指针异常,它大多数时候都有效,但有时会抛出NPE,它是一个运行的服务类型应用程序在后台,每个方法都打开一个与数据库的连接,并在使用后关闭它。每个方法都有一个同步锁,以便在连接到DB期间不会发生冲突。

public Configuration getConfiguration() {
    String sql = "SELECT * FROM tbl_settings;";
    HashMap<String, String> map = new HashMap<String, String>();

    synchronized (_synchObject){
    try {
        open();
        PreparedStatement stmt = (PreparedStatement) conn.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
           >>line 495: map.put(rs.getString("Field"), rs.getString("Value"));   //NPE is thrown in this line: 495
        }
    } catch (SQLException e) {
        logger.error(e);
    } finally {
        try {
            close();
        } catch (SQLException e) {
            logger.error(e);
        }
    }
    return new Configuration(map);
  }

这里的方法open()只是创建了与DB的连接 -

 private void open() throws SQLException {
    String connectionString = ConfigSettings.getInstance().getDatabaseConnectionString();
    conn = (Connection) DriverManager.getConnection(connectionString);
}

抛出异常 -

Exception in thread "Thread-2" java.lang.NullPointerException
at com.mysql.jdbc.ResultSetImpl.buildIndexMapping(ResultSetImpl.java:683)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1042)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5202)
at com.twora.entryexit.db.DatabaseAccess.getConfiguration(DatabaseAccess.java:495)
at com.twora.entryexit.model.Configuration.getInstance(Configuration.java:33)
at com.twora.entryexit.service.runnables.IntervalledService.runSpecific(IntervalledService.java:33)
at com.twora.entryexit.service.runnables.RunningService.run(RunningService.java:38)
at java.lang.Thread.run(Thread.java:745)

我在每次运行中运行一次查询并在此之后立即读取结果集。我该怎么做才能克服这个问题?

1 个答案:

答案 0 :(得分:1)

您在代码中获得异常,该代码在结果集中构建三个映射,这些映射将列名称和标签映射到查询中的索引。这与对getString的调用无关。

最有可能发生的是您的线程同步存在缺陷,并且您有两个线程同时处理同一个结果集对象。这是因为结果集来自连接对象,并且您有两个线程同时使用同一连接中的相同结果集对象。

在结果集中调用“close”时,将清除该结果集中的映射。所以你有一个线程关闭结果集,而另一个线程仍在使用它。这也解释了为什么它在某些时候起作用,这一切都取决于时机。

我可以在你的代码中看到你用来同步的对象不清楚。您需要确保您没有同时在两个单独的线程中使用相同的连接对象,并且您的同步此时无法执行此操作。