I have a program in which i need to connect to my postgreSQL DB. I have 4 classes:
public class FileReader {
public Stream<String> readFileFromResource(String path) throws URISyntaxException, IOException {
Path result = Paths.get(getClass().getClassLoader().getResource(path).toURI());
return Files.lines(result);
}
}
and
public class SQLQueryExecutor {
public void executeSQL(Connection connection, String sqlContents) throws SQLException {
try (Statement statement = connection.createStatement()){
statement.execute(sqlContents);
}finally {
connection.close();
}
}
}
and
public class SQLFileExecutor {
public void executeSQLFile(Connection connection, String path) throws URISyntaxException, IOException {
FileReader fr = new FileReader();
SQLQueryExecutor sqlQueryExecutor = new SQLQueryExecutor();
fr.readFileFromResource(path).forEach(i -> {
try {
sqlQueryExecutor.executeSQL(connection, i);
} catch (SQLException e) {
System.out.println("Table is not created");
e.printStackTrace();
}
});
}
}
and
public class SchoolApp {
private static final String USER = "user1";
private static final String PASSWORD = "01234";
private static final String URL = "jdbc:postgresql://localhost:5432/school";
public static void main(String[] args) throws SQLException, URISyntaxException, IOException {
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
SQLFileExecutor sqlFileExecutor = new SQLFileExecutor();
sqlFileExecutor.executeSQLFile(connection, "CreateTables.sql");
}
}
Unfortunately, I have an error: the connection has already been closed. I don't get it why I have this error. Maybe the reason is that I should have the statement initialization and connection closing in one method?
the error:
Table is not created
org.postgresql.util.PSQLException: Connection has already been closed
at org.postgresql.jdbc.PgConnection.checkClosed(PgConnection.java:885)
at org.postgresql.jdbc.PgConnection.createStatement(PgConnection.java:1727)
at org.postgresql.jdbc.PgConnection.createStatement(PgConnection.java:431)
at school_app.SQLQueryExecutor.executeSQL(SQLQueryExecutor.java:11)
at school_app.SQLFileExecutor.lambda$0(SQLFileExecutor.java:14)
at java.base/java.nio.file.FileChannelLinesSpliterator.forEachRemaining(FileChannelLinesSpliterator.java:117)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
at school_app.SQLFileExecutor.executeSQLFile(SQLFileExecutor.java:12)
at school_app.SchoolApp.main(SchoolApp.java:17)
SQLQueryExecutorand try to reuse that connection again. You should not close the connection inSQLQueryExecutorbut rather where you open it: inSchoolApp.main