Make lastInsertedId return null on failure.

Since we're rejiggering, we'll take this opportunity to eliminate the use of -1
as a sentinel id. Maybe your database id generator returns -1. Unlikely, but
not impossible.
This commit is contained in:
Michael Bayne
2014-05-02 13:07:05 -07:00
parent a473ff2ef1
commit 5356672130
5 changed files with 18 additions and 16 deletions
@@ -38,18 +38,19 @@ public abstract class BaseLiaison implements DatabaseLiaison
@Deprecated @Deprecated
public int lastInsertedId (Connection conn, String table, String column) throws SQLException { public int lastInsertedId (Connection conn, String table, String column) throws SQLException {
return lastInsertedId(conn, null, table, column); Integer id = lastInsertedId(conn, null, table, column);
return (id == null) ? -1 : id;
} }
// from DatabaseLiaison // from DatabaseLiaison
public int lastInsertedId (Connection conn, Statement istmt, String table, String column) public Integer lastInsertedId (Connection conn, Statement istmt, String table, String column)
throws SQLException throws SQLException
{ {
// if this JDBC driver supports getGeneratedKeys, use it! // if this JDBC driver supports getGeneratedKeys, use it!
if (istmt != null && conn.getMetaData().supportsGetGeneratedKeys()) { if (istmt != null && conn.getMetaData().supportsGetGeneratedKeys()) {
return istmt.getGeneratedKeys().getInt(column); return istmt.getGeneratedKeys().getInt(column);
} }
return -1; return null;
} }
// from DatabaseLiaison // from DatabaseLiaison
@@ -55,8 +55,9 @@ public interface DatabaseLiaison
* *
* @param istmt the insert statement that generated the keys. May be null if the ORM doesn't * @param istmt the insert statement that generated the keys. May be null if the ORM doesn't
* have the statement handy. * have the statement handy.
* @return the requested inserted id, or null if no last inserted id can be obtained.
*/ */
public int lastInsertedId (Connection conn, Statement istmt, String table, String column) public Integer lastInsertedId (Connection conn, Statement istmt, String table, String column)
throws SQLException; throws SQLException;
/** /**
@@ -73,11 +73,11 @@ public class HsqldbLiaison extends BaseLiaison
} }
@Override // from DatabaseLiaison @Override // from DatabaseLiaison
public int lastInsertedId (Connection conn, Statement istmt, String table, String column) public Integer lastInsertedId (Connection conn, Statement istmt, String table, String column)
throws SQLException throws SQLException
{ {
int id = super.lastInsertedId(conn, istmt, table, column); Integer id = super.lastInsertedId(conn, istmt, table, column);
if (id >= 0) return id; if (id != null) return id;
// HSQL does not keep track of per-table-and-column insertion data, so we are pretty much // HSQL does not keep track of per-table-and-column insertion data, so we are pretty much
// going on blind faith here that we're fetching the right ID. In the overwhelming number // going on blind faith here that we're fetching the right ID. In the overwhelming number
@@ -86,7 +86,7 @@ public class HsqldbLiaison extends BaseLiaison
try { try {
stmt = conn.createStatement(); stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("call IDENTITY()"); ResultSet rs = stmt.executeQuery("call IDENTITY()");
return rs.next() ? rs.getInt(1) : -1; return rs.next() ? rs.getInt(1) : null;
} finally { } finally {
JDBCUtil.close(stmt); JDBCUtil.close(stmt);
} }
@@ -50,14 +50,14 @@ public class MySQLLiaison extends BaseLiaison
} }
@Override // from DatabaseLiaison @Override // from DatabaseLiaison
public int lastInsertedId (Connection conn, Statement istmt, String table, String column) public Integer lastInsertedId (Connection conn, Statement istmt, String table, String column)
throws SQLException throws SQLException
{ {
// MySQL hackily reports the last inserted key as GENERATED_KEY, so we call super with that // MySQL hackily reports the last inserted key as GENERATED_KEY, so we call super with that
// "column name"; but if that doesn't work (we're using an old JDBC driver without support // "column name"; but if that doesn't work (we're using an old JDBC driver without support
// for returning generated keys), fall back to the old old method // for returning generated keys), fall back to the old old method
int id = super.lastInsertedId(conn, istmt, table, "GENERATED_KEY"); Integer id = super.lastInsertedId(conn, istmt, table, "GENERATED_KEY");
if (id >= 0) return id; if (id != null) return id;
// MySQL does not keep track of per-table-and-column insertion data, so we are pretty much // MySQL does not keep track of per-table-and-column insertion data, so we are pretty much
// going on blind faith here that we're fetching the right ID. In the overwhelming number // going on blind faith here that we're fetching the right ID. In the overwhelming number
@@ -66,7 +66,7 @@ public class MySQLLiaison extends BaseLiaison
try { try {
stmt = conn.createStatement(); stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select LAST_INSERT_ID()"); ResultSet rs = stmt.executeQuery("select LAST_INSERT_ID()");
return rs.next() ? rs.getInt(1) : -1; return rs.next() ? rs.getInt(1) : null;
} finally { } finally {
JDBCUtil.close(stmt); JDBCUtil.close(stmt);
} }
@@ -35,12 +35,12 @@ public class PostgreSQLLiaison extends BaseLiaison
} }
// from DatabaseLiaison // from DatabaseLiaison
public int lastInsertedId (Connection conn, Statement istmt, String table, String column) public Integer lastInsertedId (Connection conn, Statement istmt, String table, String column)
throws SQLException throws SQLException
{ {
// try the default first, which uses JDBC's getGeneratedKeys mechanism // try the default first, which uses JDBC's getGeneratedKeys mechanism
int id = super.lastInsertedId(conn, istmt, table, column); Integer id = super.lastInsertedId(conn, istmt, table, column);
if (id >= 0) return id; if (id != null) return id;
// PostgreSQL's support for auto-generated ID's comes in the form of appropriately named // PostgreSQL's support for auto-generated ID's comes in the form of appropriately named
// sequences and DEFAULT nextval(sequence) modifiers in the ID columns. To get the next ID, // sequences and DEFAULT nextval(sequence) modifiers in the ID columns. To get the next ID,
@@ -50,7 +50,7 @@ public class PostgreSQLLiaison extends BaseLiaison
try { try {
ResultSet rs = stmt.executeQuery( ResultSet rs = stmt.executeQuery(
"select currval('\"" + table + "_" + column + "_seq\"')"); "select currval('\"" + table + "_" + column + "_seq\"')");
return rs.next() ? rs.getInt(1) :-1; return rs.next() ? rs.getInt(1) : null;
} finally { } finally {
JDBCUtil.close(stmt); JDBCUtil.close(stmt);
} }