简体   繁体   English

Java项目的不稳定Oracle数据库连接

[英]Unstable Oracle Database connection for Java-project

I'm a student and one of our assignments is creating a Java web project on a local GlassFish 5 webserver. 我是一名学生,我们的一项任务是在本地GlassFish 5 Web服务器上创建一个Java Web项目。 The database used for this project is an OracleDB running locally in a Docker container. 用于该项目的数据库是在Docker容器中本地运行的OracleDB。

I almost finished my project but some pages keep crashing (NullPointerException). 我几乎完成了我的项目,但某些页面不断崩溃(NullPointerException)。 I have to retrieve database records and save them in an ArrayList. 我必须检索数据库记录并将其保存在ArrayList中。 But sometimes the SQLConnection doesn't return anything (but the records DO exist) and my code tries to preform actions on that empty ArrayList. 但是有时SQLConnection不返回任何东西(但是记录确实存在),并且我的代码尝试对空ArrayList执行操作。

Now, as I said, the connection appears to be unstable, because at some seemingly random moments the database does respond with the appropriate records. 现在,正如我所说,连接似乎不稳定,因为在某些看似随机的时刻,数据库确实会响应适当的记录。

It's really frustrating and I cannot continue working on this project without a stable database connection. 确实令人沮丧,如果没有稳定的数据库连接,我将无法继续从事该项目。 So I'd appreciate hearing from people with some more experience :-) 因此,我希望能收到更多经验的人的帮助:-)

Thank you for your time. 感谢您的时间。

Code for running a query: 用于运行查询的代码:

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;
    }

Code with the query: 查询代码:

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.

I think this is the actual error message: Listener refused the connection with the following error: ORA-12519, TNS:no appropriate service handler found 我认为这是实际的错误消息:侦听器拒绝了以下错误的连接:ORA-12519,TNS:找不到合适的服务处理程序

But I don't really understand what I should do now.. 但是我真的不明白我现在应该做什么。

 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;

It might be nothing, but it almost looks like the error only occurs when I run 2 queries almost immediately after each other. 可能什么也不是,但是几乎看起来只有在我紧接彼此运行2个查询时才会发生错误。 Is it possible that closing the connection takes a while? 关闭连接是否可能需要一段时间?

Chances are that you run into the database connection problem because your code does not properly close the database connections as well as the statements and result sets. 您可能会遇到数据库连接问题,因为您的代码无法正确关闭数据库连接以及语句和结果集。

A statement will also close its active result set. 一条语句还将关闭其活动结果集。 Most JDBC will also close the statement if the connection is closed. 如果连接关闭,大多数JDBC也会关闭该语句。

So closing the connection is the most important part. 因此,关闭连接是最重要的部分。 It cannot be achieved with your current code structure because you create it in an inner method and do not return it. 当前的代码结构无法实现它,因为您是在内部方法中创建它的,并且不返回它。

It has also been mentioned that the exception handling is poor because you ignore exceptions and return null instead causing seemingly unrelated crashes later. 还提到了异常处理很差,因为您忽略异常并返回null,而不是稍后导致看似无关的崩溃。 In many cases it might be easier to declare that the method throws SQLException . 在许多情况下,声明该方法引发SQLException可能会更容易。

You might want to change your code like so: 您可能想要像这样更改代码:

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;
}

It closes the connection, the statement and the result set by using try/catch blocks that take advantage of AutoClosable s (in this case: Connection , Statement , ResultSet ). 通过使用利用AutoClosable的try / catch块(在本例中为ConnectionStatementResultSet ),它关闭连接,语句和结果集。

The method processResultSet declares the SQLException so it doesn't need to handle it. 方法processResultSet声明了SQLException因此不需要处理它。

The code is rearrange so the data is fully processed before the code leaves the try/catch block that closes the connection. 代码经过重新排列,因此在代码离开try / catch块关闭连接之前,已对数据进行了完全处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM