Sample Header Ad - 728x90

How do I update Java prepared statements from Postgres 12 to Postgres 16?

0 votes
2 answers
57 views
I have a Java/JSP webapp that uses a Postgres database. I recently migrated the webapp from one server running Ubuntu 20.04 and Postgres 12 to another server running Ubuntu 24.04 and Postgres 16. I've found that the webapp now generates a Postgres-related error
org.postgresql.util.PSQLException: ERROR: trailing junk after parameter at or near "$5WHERE"
with a reference to one of the Java class files in the webapp. That file generates an SQL query using Java's prepared statements to execute on the Postgres database. The exact string "$5WHERE" appears nowhere in my source code, but of course there are several instances of the SQL keyword " WHERE " (surrounded by spaces) in the file in question. **Question 1:** Where does the "$5" come from in the error message "$5WHERE"? I can't find any reference to this online, and it might be a clue. The closest example I can find online to the error message as a whole is this [StackExchange](https://stackoverflow.com/questions/75482094/postgresql-15-trailing-junk-after-numeric-literal-error) question from 2023. The question cites the recent transition to Postgres 15 and its [release notes](https://www.postgresql.org/docs/15/release-15.html) that states one change is > Prevent numeric literals from having non-numeric trailing characters (Peter Eisentraut) § > Previously, query text like 123abc would be interpreted as 123 followed by a separate token abc. I'm not certain this is related to my error. The only numeric literal data I have in the problem code is a primary key, and I'm sure it doesn't have trailing characters. I've pulled all of the code I can tell is relevant from the Java class cited in the error and cleaned it up as best I can:
import java.sql.Connection;
import java.sql.PreparedStatement;

public void updateUser(WorkGroup group, String password) {

    PreparedStatement ps = null, ps2 = null;
    Connection conn = DBManager.getConnection();
    conn.setAutoCommit(false);

    // Whether the user's password is being updated
    boolean pass = false;

    String sql = "UPDATE user_record SET join = ?, role = ?, sales_training = ?, sec_training = ?, field_training = ?";

    if (StringUtils.isNotBlank(password)) {
        sql += ", hashedpassword = ? ";
        pass = true;
    }

    sql += "WHERE id = ?;";
    ps = conn.prepareStatement(sql);
    ps.setString(1, group.getJoinYear());
    ps.setString(2, group.getRole());
    ps.setBoolean(3, group.getSalesTraining());
    ps.setBoolean(4, group.getSecTraining());
    ps.setBoolean(5, group.getFieldTraining());

    if (pass) {
        String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt(12));
        ps.setString(6, hashedPassword);
        ps.setInt(7, group.getId());
    }
    else {
        ps.setInt(6, group.getId());
    }

    ps.executeUpdate();

}
I want to stress that this code has worked for years, so there can't be anything fundamentally wrong with it. My top suspicion is that this manner of preparing the SQL statement conflicts with a change in one of the Postgres major versions between 12 and 16, but I can't tell what because the statement preparation obscures so much. **Question 2:** Does this code need updating to remain current with Postgres, and what needs to be updated?
Asked by Borea Deitz (151 rep)
Jun 3, 2025, 08:26 PM
Last activity: Jun 4, 2025, 09:29 AM