From 0ea70f2f6ff6568e70d4ebbf2497dc4fcc94935d Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 7 Jul 2026 14:59:52 +1200 Subject: [PATCH] Fix findVersions() unbound bind parameters on sql2011 history platforms On standards-based platforms (MariaDB, SQL Server, Oracle, DB2, HANA) the root table always generates a 'for system_time between ? and ?' clause for TemporalMode.VERSIONS, but bind values were only supplied for findVersionsBetween(), leaving findVersions() with 2 unbound placeholders and shifted bind positions ("Parameter at position N is not set"). Match the bind guard to the SQL generation condition and default start/end to epoch/now when not explicit. --- .../server/query/CQueryPredicates.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java index db76c9d5b0..56aeb96e2a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java @@ -33,6 +33,13 @@ */ public final class CQueryPredicates { + /** + * Default lower bound used for findVersions() (no explicit start/end) on sql2011 + * standards based platforms that require actual bind values for the root table's + * 'for system_time between ? and ?' clause. + */ + private static final Timestamp EPOCH = Timestamp.valueOf("1970-01-01 00:00:00"); + private final Binder binder; private final OrmQueryRequest request; private final SpiQuery query; @@ -84,10 +91,16 @@ public String bind(DataBind dataBind) throws SQLException { // bind the update set clause updateProperties.bind(binder, dataBind); } - if (query.isVersionsBetween() && binder.isAsOfStandardsBased()) { + if (binder.isAsOfStandardsBased() && query.temporalMode() == SpiQuery.TemporalMode.VERSIONS) { // sql2011 based versions between timestamp syntax Timestamp start = query.versionStart(); Timestamp end = query.versionEnd(); + if (start == null) { + start = EPOCH; + } + if (end == null) { + end = new Timestamp(System.currentTimeMillis()); + } dataBind.append("between ").append(start).append(" and ").append(end); binder.bindObject(dataBind, start); binder.bindObject(dataBind, end);