当我将结果集中的值放入地图时,我在以下代码中显示的行中得到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)
我在每次运行中运行一次查询并在此之后立即读取结果集。我该怎么做才能克服这个问题?
答案 0 :(得分:1)
您在代码中获得异常,该代码在结果集中构建三个映射,这些映射将列名称和标签映射到查询中的索引。这与对getString的调用无关。
最有可能发生的是您的线程同步存在缺陷,并且您有两个线程同时处理同一个结果集对象。这是因为结果集来自连接对象,并且您有两个线程同时使用同一连接中的相同结果集对象。
在结果集中调用“close”时,将清除该结果集中的映射。所以你有一个线程关闭结果集,而另一个线程仍在使用它。这也解释了为什么它在某些时候起作用,这一切都取决于时机。
我可以在你的代码中看到你用来同步的对象不清楚。您需要确保您没有同时在两个单独的线程中使用相同的连接对象,并且您的同步此时无法执行此操作。