Andrey
Andrey

Reputation: 51

Catching Java SQLExceptions

I do not have a lot of experience in Java and would appreciate if you bring a light on the question.

I have the following piece of code (method) to establish the JDBC connection with a PostgreSQL database :

public void establishDBConnection() throws SQLException {

    try (Connection connection = DriverManager.getConnection(
                "jdbc:postgresql://" + dbServer + ":" + dbPort + "/" + 
                dbDatabase, dbUser, dbPassword))
    catch (SQLException e) {
        logger.error("Connection to Postgres Database Failed: " + 
        e.printStackTrace();
    }
 }

I expect that the SQLException would be caught by the catch block as soon as the method can't establish connection with the database (server is down). The catch block puts the exception on the console but I see that the same exception is displayed earlier right after the getConnection method execution. Thus, I have 2 quite the same exceptions on the console. See below.

The question is what is the reason for this and how to force the application to display only the exception generated by the catch block.

Logs:

Jul 07, 2017 9:11:53 PM org.postgresql.Driver connect
SEVERE: Connection error: 
**org.postgresql.util.PSQLException: Connection to localhost:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.**
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:265)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194)
    at org.postgresql.Driver.makeConnection(Driver.java:431)
    at org.postgresql.Driver.connect(Driver.java:247)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at excel2db.service.impl.DBConnectionPostgresImpl.establishDBConnection(DBConnectionPostgresImpl.java:38)
    at excel2db.excel2db.main(excel2db.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.postgresql.core.PGStream.<init>(PGStream.java:62)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
    ... 13 more

21:11:53.465 [main] ERROR e.s.impl.DBConnectionPostgresImpl - **Connection to Postgres Database Failed: Connection to localhost:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.**

Upvotes: 1

Views: 2700

Answers (2)

Mandeep Singh
Mandeep Singh

Reputation: 101

You need to load the driver's class into memory. Try This code :

try {
    Class.forName("org.postgresql.Driver");

    Connection connection = DriverManager.getConnection(jdbc:postgresql://server_address:5432/database_name?user=usernam&password=password);

} catch (Exception exception) {
    exception.printStackTrace();
}

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691645

There is only one exception being printed in your example: the SQLException being caught. What you think is a second exception is only (as the text shows) the cause of the SQLException: Postgres throws a SQLException, which is itself being thrown because there was a network ConnectException when Portgres tried to connect.

This chain of exceptions is very handy when you need to diagnose a failure. It allows going back to the original, low-level source of a problem. Just like, for example, it can be useful to know that you didn't got your mail (NoMailException) because the post office is on strike (OnStrikeException), because the government decided to lower the wages (WagesTooLowException). If you just had the original NoMailException, you wouldn't be able to know the reason why you got no mail, know that it's probably temporary, etc.

In this particular case, you can deduce that it was impossible to connect to the server, and not for example, that the password was incorrect.

Chaining exceptions is simply achieved by calling one of the exception constructors that take another exception as argument (most exceptions do). See https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html#Exception-java.lang.String-java.lang.Throwable-.

Upvotes: 3

Related Questions