@@ -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