Нестабильное соединение с Oracle Database для Java-проекта

Я студент, и одним из наших заданий является создание веб-проекта на Java на локальном веб-сервере GlassFish 5. База данных, используемая для этого проекта, - OracleDB, работающая локально в контейнере Docker.

Я почти закончил свой проект, но некоторые страницы продолжают падать (NullPointerException). Я должен получить записи базы данных и сохранить их в ArrayList. Но иногда SQLConnection ничего не возвращает (но записи действительно существуют), и мой код пытается выполнить действия для этого пустого ArrayList.

Теперь, как я уже сказал, соединение кажется нестабильным, потому что в некоторые, казалось бы, случайные моменты база данных отвечает соответствующими записями.

Это действительно расстраивает, и я не могу продолжать работать над этим проектом без стабильного соединения с базой данных. Так что я был бы рад услышать от людей с большим опытом:-)

Спасибо за ваше время.

Код для запуска запроса:

protected ResultSet getRecords(String query) {
        try {
            Connection connection = DriverManager.getConnection(url, login, password);
            Statement statement = connection.createStatement();
            return (ResultSet) statement.executeQuery(query);
        } catch (SQLException e) {
            e.getStackTrace();
        } 
        return null;
    }

Код с запросом:

List<Uitlening> uitleningen = new ArrayList<Uitlening>();

        try {
            ResultSet resultSet = getRecords("SELECT * FROM uitlening");

            while(resultSet.next()) { //Here the code crashes because the ResultSet can sometimes be empty.

Я думаю, что это фактическое сообщение об ошибке: слушатель отклонил соединение со следующей ошибкой: ORA-12519, TNS: не найден соответствующий обработчик службы

Но я не очень понимаю, что мне делать сейчас..

 try {
        ResultSet resultSet = getRecords("SELECT * FROM uitlening");

        while(resultSet.next()) { 
            Uitlening uitlening = new Uitlening();
            uitlening.setNr(resultSet.getInt("nr"));                
            uitleningen.add(uitlening);
        }
    } catch (SQLException e) {
        e.addSuppressed(e);
    } 
    return uitleningen;

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

1 ответ

Решение

Скорее всего, вы столкнетесь с проблемой соединения с базой данных, поскольку ваш код неправильно закрывает соединения с базой данных, а также операторы и наборы результатов.

Оператор также закроет свой активный набор результатов. Большинство JDBC также закроет оператор, если соединение закрыто.

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

Также было упомянуто, что обработка исключений плохая, потому что вы игнорируете исключения и возвращаете нуль, вместо этого вызывая, по-видимому, несвязанные сбои позже. Во многих случаях было бы легче объявить, что метод SQLException,

Вы можете изменить свой код следующим образом:

List<Uitlening> retrieveData() {
    final String query = "SELECT * FROM uitlening";
    try (Connection connection = DriverManager.getConnection(url, login, password);
         Statement statement = connection.createStatement();
         ResultSet resultSet = statement.executeQuery(query)) {
        return processResultSet(resultSet);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

List<Uitlening> processResultSet(ResultSet resultSet) throws SQLException {
    List<Uitlening> uitleningen = new ArrayList<>();
    while (resultSet.next()) {
        Uitlening uitlening = new Uitlening();
        uitlening.setNr(resultSet.getInt("nr"));
        uitleningen.add(uitlening);
    }
    return uitleningen;
}

Он закрывает соединение, оператор и набор результатов, используя блоки try/catch, которые используют преимущества AutoClosables (в этом случае: Connection, Statement, ResultSet).

Метод processResultSet объявляет SQLException так что не нужно с этим справляться.

Код переупорядочен, поэтому данные полностью обрабатываются, прежде чем код покидает блок try/catch, закрывающий соединение.

Другие вопросы по тегам