From 10106688c248858feddca5ffbf0408065e1890f3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 10 Apr 2026 00:03:57 +1200 Subject: [PATCH] Fix for @Column on timestamp defined as timestamp(255) As per https://github.com/ebean-orm/ebean/discussions/3720 ``` @Column ZonedDateTime zonedDateTime2; ``` ... resulting in DDL generated as `timestamp(255)`. This is occurring when the JPA dependency is used like: jakarta.persistence:jakarta.persistence-api:3.2.0 rather than using the transitive dependency that ebean includes. Workaround: Remove the jakarta.persistence:jakarta.persistence-api:3.2.0 dependency. Fix: The fix here is to use a timestamp type that has a maximum precision. When a precision/length is specified greater than the maximum precision then the fallback type is used which is `timestamp` without any precision. --- .../config/dbplatform/DbPlatformTypeMapping.java | 10 +++++++++- .../config/dbplatform/DbPlatformTypeMappingTest.java | 12 ++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java index dfb5d885fb..60c6b31f44 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/DbPlatformTypeMapping.java @@ -51,6 +51,13 @@ protected void renderLengthScale(int deployLength, int deployScale, StringBuilde private static final DbPlatformType VECTOR_BIT = new DbPlatformType("bit", 64000, null); private static final DbPlatformType VECTOR_SPARSE = new DbPlatformType("sparsevec", 1000, null); + /** + * Timestamp with max precision of 15, and fallback to plain timestamp without precision defined. + */ + private static final DbPlatformType TIMESTAMP = + new DbPlatformType("timestamp", 0, 15, + new DbPlatformType("timestamp", false)); + private final Map typeMap = new EnumMap<>(DbType.class); /** @@ -87,7 +94,8 @@ private void loadDefaults(boolean logicalTypes) { put(DbType.ARRAY); put(DbType.DATE); put(DbType.TIME); - put(DbType.TIMESTAMP); + put(DbType.TIMESTAMP, TIMESTAMP); + put(DbType.LONGVARBINARY); put(DbType.LONGVARCHAR); // most commonly real maps to db float diff --git a/ebean-test/src/test/java/io/ebean/xtest/config/dbplatform/DbPlatformTypeMappingTest.java b/ebean-test/src/test/java/io/ebean/xtest/config/dbplatform/DbPlatformTypeMappingTest.java index a20ecbca94..a9abf7cefb 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/config/dbplatform/DbPlatformTypeMappingTest.java +++ b/ebean-test/src/test/java/io/ebean/xtest/config/dbplatform/DbPlatformTypeMappingTest.java @@ -2,16 +2,17 @@ import io.ebean.config.dbplatform.DbPlatformType; import io.ebean.config.dbplatform.DbPlatformTypeMapping; +import io.ebean.config.dbplatform.DbType; import org.junit.jupiter.api.Test; import java.sql.Types; import static org.assertj.core.api.Assertions.assertThat; -public class DbPlatformTypeMappingTest { +class DbPlatformTypeMappingTest { @Test - public void logicalBoolean_renderType_expect_noLength() { + void logicalBoolean_renderType_expect_noLength() { DbPlatformTypeMapping logicalMapping = DbPlatformTypeMapping.logicalTypes(); @@ -19,4 +20,11 @@ public void logicalBoolean_renderType_expect_noLength() { String colDefinition = type.renderType(1, 1, false); assertThat(colDefinition).isEqualTo("boolean"); } + + @Test + void timestamp_with_255_expectNoPrecision() { + DbPlatformType timestampType = new DbPlatformTypeMapping().get(DbType.TIMESTAMP); + String colDefinition = timestampType.renderType(255, 0, true); + assertThat(colDefinition).isEqualTo("timestamp"); + } }