1

So I'm trying to add to database using JDBC from files. And now when INSERTING I need to get the ID before I insert and it would be better If the database would still use the sequence.

In folder resources I have a file called insert_plant.sql that contains this query:

INSERT INTO PLANTS (id, plantname, species)
  VALUES (NEXT VALUE FOR sequence, ?, null);

And the table is generated with this:

DROP SCHEMA public CASCADE;

CREATE SEQUENCE sequence START WITH 1;

CREATE TABLE PLANTS (
   id BIGINT NOT NULL PRIMARY KEY,
   plantname VARCHAR(255) NOT NULL,
   species VARCHAR(255) NULL,
);

And now in Java I am calling this:

public static void insertIntoOrderTable(BasicDataSource basicDataSource, String plantname) throws  SQLException{
    Connection conn = null;
    PreparedStatement stmt = null;

    try {
        conn = basicDataSource.getConnection();
        stmt = conn.prepareStatement(Util.readFileFromClasspath("insert_plant.sql"));
        stmt.setString(1, plantname);
        stmt.executeUpdate();

        //Below is the line 57 (in error)
        ResultSet rs = stmt.executeQuery("SELECT sequence.NEXTVAL FROM PLANTS");
        if(rs.next()){
            System.out.println("ID" + rs.getInt(1));
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    }
}

And the error I get:

java.sql.SQLFeatureNotSupportedException: feature not supported
at org.hsqldb.jdbc.JDBCUtil.notSupported(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
at database.PlantDao.insertIntoOrderTable(PlantDao.java:57)
at database.PlantDao.main(PlantDao.java:19)

So the question

7
  • 1
    What RDBMS are you using? Commented Oct 15, 2018 at 14:36
  • 1
    It's probably not the source of your problem but it's not a good idea to use reserved keywords for variable names, naming your sequence sequence in this case. Commented Oct 15, 2018 at 14:37
  • @StephaneM i just put it here to be more understandable Commented Oct 15, 2018 at 14:42
  • @Andrew I am using hsqldb Commented Oct 15, 2018 at 14:44
  • For H2, I think the sytax is NEXTVAL('SequenceName'). Commented Oct 15, 2018 at 14:44

1 Answer 1

1

As already commented by ´The Impaler` there is no need to execute a second statement, with JDBC you can use

PreparedStatement stmt = conn.prepareStatement(sql, new String[]{"id"});

And to get the value out of it:

ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
    System.out.println(rs.getLong(1));
}

So your method would look something like this:

public static void insertIntoOrderTable(BasicDataSource basicDataSource, String plantname) throws  SQLException{
    Connection conn = null;
    PreparedStatement stmt = null;

    try {
        conn = basicDataSource.getConnection();
        stmt = conn.prepareStatement(Util.readFileFromClasspath("insert_plant.sql"), new String[]{"id"});
        stmt.setString(1, plantname);
        stmt.executeUpdate();

        ResultSet rs = stmt.getGeneratedKeys();
        if(rs.next()){
            System.out.println(rs.getLong(1));
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This still does not work with MSSQL github.com/Microsoft/mssql-jdbc/issues/656 :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.