Skip to content

Commit 8e14571

Browse files
Fix createBackfillRevision to insert explicit id for non-auto-increment revision_entity table
1 parent 0775dcd commit 8e14571

File tree

1 file changed

+50
-10
lines changed

1 file changed

+50
-10
lines changed

api/src/main/java/org/openmrs/util/EnversAuditTableInitializer.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ private static Integer tryBackfillEntity(Connection connection, String sourceTab
211211
if (revId == null) {
212212
revId = createBackfillRevision(connection, revisionTableName);
213213
}
214-
List<String> columns = getSourceTableColumns(connection, sourceTable);
214+
List<String> columns = getAuditTableDataColumns(connection, auditTable);
215215
if (!columns.isEmpty()) {
216216
backfillTable(connection, sourceTable, auditTable, columns, revId);
217217
}
@@ -231,19 +231,40 @@ private static Integer tryBackfillEntity(Connection connection, String sourceTab
231231
* @throws SQLException if the revision entry cannot be created
232232
*/
233233
static int createBackfillRevision(Connection connection, String revisionTableName) throws SQLException {
234+
String pkColumn = getRevisionPrimaryKeyColumn(connection, revisionTableName);
234235
String timestampColumn = getRevisionTimestampColumn(connection, revisionTableName);
235-
String sql = "INSERT INTO " + requireSafeIdentifier(revisionTableName) + " ("
236-
+ requireSafeIdentifier(timestampColumn) + ") VALUES (?)";
237-
try (PreparedStatement pstmt = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
238-
pstmt.setLong(1, System.currentTimeMillis());
236+
int nextId;
237+
try (Statement stmt = connection.createStatement();
238+
ResultSet rs = stmt.executeQuery("SELECT COALESCE(MAX(" + requireSafeIdentifier(pkColumn) + "), 0) + 1 FROM "
239+
+ requireSafeIdentifier(revisionTableName))) {
240+
nextId = rs.next() ? rs.getInt(1) : 1;
241+
}
242+
String sql = "INSERT INTO " + requireSafeIdentifier(revisionTableName) + " (" + requireSafeIdentifier(pkColumn)
243+
+ ", " + requireSafeIdentifier(timestampColumn) + ") VALUES (?, ?)";
244+
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
245+
pstmt.setInt(1, nextId);
246+
pstmt.setLong(2, System.currentTimeMillis());
239247
pstmt.executeUpdate();
240-
try (ResultSet rs = pstmt.getGeneratedKeys()) {
241-
if (rs.next()) {
242-
return rs.getInt(1);
243-
}
248+
return nextId;
249+
}
250+
}
251+
252+
/**
253+
* Discovers the primary key column name of the revision entity table.
254+
*
255+
* @param connection JDBC connection
256+
* @param revisionTableName name of the revision entity table
257+
* @return the primary key column name, falling back to "id" if not found
258+
* @throws SQLException if metadata cannot be read
259+
*/
260+
static String getRevisionPrimaryKeyColumn(Connection connection, String revisionTableName) throws SQLException {
261+
DatabaseMetaData metaData = connection.getMetaData();
262+
try (ResultSet rs = metaData.getPrimaryKeys(null, null, revisionTableName)) {
263+
if (rs.next()) {
264+
return rs.getString("COLUMN_NAME");
244265
}
245266
}
246-
throw new SQLException("Failed to create backfill revision entry in " + revisionTableName);
267+
return "id";
247268
}
248269

249270
/**
@@ -328,6 +349,25 @@ static List<String> getSourceTableColumns(Connection connection, String tableNam
328349
return columns;
329350
}
330351

352+
/**
353+
* Returns the data column names from the given audit table, excluding the Envers metadata columns
354+
* REV and REVTYPE. These are the columns that correspond to the audited entity fields and must
355+
* exist in the source table.
356+
*/
357+
static List<String> getAuditTableDataColumns(Connection connection, String auditTable) throws SQLException {
358+
List<String> columns = new ArrayList<>();
359+
DatabaseMetaData metaData = connection.getMetaData();
360+
try (ResultSet rs = metaData.getColumns(null, null, auditTable, null)) {
361+
while (rs.next()) {
362+
String colName = rs.getString("COLUMN_NAME");
363+
if (!colName.equalsIgnoreCase("REV") && !colName.equalsIgnoreCase("REVTYPE")) {
364+
columns.add(colName);
365+
}
366+
}
367+
}
368+
return columns;
369+
}
370+
331371
/**
332372
* Inserts all rows from the source table into the audit table with REVTYPE=0 (ADD).
333373
*/

0 commit comments

Comments
 (0)