@@ -222,16 +222,18 @@ private static Integer tryBackfillEntity(Connection connection, String sourceTab
222222 }
223223
224224 /**
225- * Creates a backfill revision entry in the revision entity table. Uses the REVTSTMP column which is
226- * explicitly defined in Hibernate's RevisionMapping with @Column(name = "REVTSTMP") .
225+ * Creates a backfill revision entry in the revision entity table. Dynamically discovers the
226+ * timestamp column name from JDBC metadata to avoid hardcoding Hibernate-version-specific names .
227227 *
228228 * @param connection JDBC connection
229229 * @param revisionTableName name of the revision entity table
230230 * @return the generated revision ID
231231 * @throws SQLException if the revision entry cannot be created
232232 */
233233 static int createBackfillRevision (Connection connection , String revisionTableName ) throws SQLException {
234- String sql = "INSERT INTO " + requireSafeIdentifier (revisionTableName ) + " (REVTSTMP) VALUES (?)" ;
234+ String timestampColumn = getRevisionTimestampColumn (connection , revisionTableName );
235+ String sql = "INSERT INTO " + requireSafeIdentifier (revisionTableName ) + " ("
236+ + requireSafeIdentifier (timestampColumn ) + ") VALUES (?)" ;
235237 try (PreparedStatement pstmt = connection .prepareStatement (sql , Statement .RETURN_GENERATED_KEYS )) {
236238 pstmt .setLong (1 , System .currentTimeMillis ());
237239 pstmt .executeUpdate ();
@@ -244,6 +246,36 @@ static int createBackfillRevision(Connection connection, String revisionTableNam
244246 throw new SQLException ("Failed to create backfill revision entry in " + revisionTableName );
245247 }
246248
249+ /**
250+ * Discovers the timestamp column name in the revision entity table by finding the first BIGINT
251+ * column that is not the primary key. This avoids hardcoding Hibernate-version-specific names like
252+ * "REVTSTMP" which may differ across Hibernate versions.
253+ *
254+ * @param connection JDBC connection
255+ * @param revisionTableName name of the revision entity table
256+ * @return the timestamp column name, falling back to "REVTSTMP" if not found
257+ * @throws SQLException if metadata cannot be read
258+ */
259+ static String getRevisionTimestampColumn (Connection connection , String revisionTableName ) throws SQLException {
260+ DatabaseMetaData metaData = connection .getMetaData ();
261+ String pkColumn = null ;
262+ try (ResultSet pkRs = metaData .getPrimaryKeys (null , null , revisionTableName )) {
263+ if (pkRs .next ()) {
264+ pkColumn = pkRs .getString ("COLUMN_NAME" );
265+ }
266+ }
267+ try (ResultSet colRs = metaData .getColumns (null , null , revisionTableName , null )) {
268+ while (colRs .next ()) {
269+ String colName = colRs .getString ("COLUMN_NAME" );
270+ int dataType = colRs .getInt ("DATA_TYPE" );
271+ if (dataType == java .sql .Types .BIGINT && !colName .equalsIgnoreCase (pkColumn )) {
272+ return colName ;
273+ }
274+ }
275+ }
276+ return "REVTSTMP" ;
277+ }
278+
247279 /**
248280 * Validates that a SQL identifier (table or column name) contains only safe characters, preventing
249281 * SQL injection when identifiers must be concatenated into queries.
0 commit comments