2016-11-03 2 views
0

Я получаю исключение Null указателя в указанной строке в следующем коде, когда я помещаю значения из набора результатов в карту, он работает чаще всего, но иногда он бросает NPE, это приложение типа службы, которое работает в фоновом режиме, и каждый метод открывает соединение с базой данных и закрывает его после использования. Для каждого метода существует синхронизированная блокировка, поэтому при подключении к БД не возникает конфликта.Неожиданный NPE, брошенный при попытке поставить результаты запроса на карту

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

com.twora.entryexit.db.DatabaseAccess.getConfiguration (DatabaseAccess.java:495) Из этой строки я не могу понять, какая строка 495 в методе getConfiguration –

+0

Я добавил комментарий рядом с линией, бросающей NPE (строка 495) –

+0

Если это полная и правильная трассировка стека, NPE происходит в одном из вызовов 'getString()'. Можете ли вы переписать этот раздел для выполнения 'getString()' вызовов перед 'map.put()' и хранить значения во временном 'String', чтобы вы могли видеть, какой из них терпит неудачу? –

ответ

1

Вы получаете исключение в коде, который создает три карты в наборе результатов, которые сопоставляют имена столбцов и метки с их индексом в запросе. Это не имеет никакого отношения к вызовам getString.

Что, скорее всего, происходит из-за того, что ваша синхронизация потоков ошибочна, и у вас есть два потока, работающих одновременно с одним и тем же объектом набора результатов. Это происходит потому, что результирующий набор поступает от объекта соединения, и у вас есть два потока, которые используют один и тот же объект набора результатов из одного и того же соединения одновременно.

Карты в этом результирующем наборе очищаются, когда в наборе результатов вызывается «close». Таким образом, у вас есть один поток, закрывающий результирующий набор, в то время как другой поток все еще использует его. Это также объясняет, почему он работает некоторое время, все зависит от времени.

Я вижу в вашем коде, что объект, который вы используете для синхронизации, не ясен. Вам необходимо убедиться, что вы не используете один и тот же объект соединения в двух отдельных потоках одновременно, и ваша синхронизация не выполняет этого в это время.

+0

Я не думал об этом направлении. Спасибо, Для ясности. Вы подразумеваете, что может быть метод, который не находится внутри синхронизированного оператора? –

+0

Я увидел метод, который открывался, работая над результирующим набором и закрывая соединение с БД, которое не было внутри синхронизированного оператора. Изменено, теперь выполняется тест. Будет опубликовать обновления. Спасибо @Sean –

+0

Я принимаю это как ответ, поскольку он указывает мне на мысль в правильном направлении, и до сих пор не добавляется NPE. –

Смежные вопросы