diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 91ff0bd9b..4e4278cdc 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,7 +1,10 @@
name: Build
-on: [push, pull_request]
+on:
+ pull_request:
+ push:
+ branches: master
jobs:
build:
diff --git a/composites/ebean-clickhouse/pom.xml b/composites/ebean-clickhouse/pom.xml
index 1327456b0..06d7b16a7 100644
--- a/composites/ebean-clickhouse/pom.xml
+++ b/composites/ebean-clickhouse/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-clickhouse
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-cockroach/pom.xml b/composites/ebean-cockroach/pom.xml
index 2bda7c244..20acfa443 100644
--- a/composites/ebean-cockroach/pom.xml
+++ b/composites/ebean-cockroach/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-postgres
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-db2/pom.xml b/composites/ebean-db2/pom.xml
index 364bc8759..18567b46d 100644
--- a/composites/ebean-db2/pom.xml
+++ b/composites/ebean-db2/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-db2
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-h2/pom.xml b/composites/ebean-h2/pom.xml
index 867d9aa58..e99c020f1 100644
--- a/composites/ebean-h2/pom.xml
+++ b/composites/ebean-h2/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-h2
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-hana/pom.xml b/composites/ebean-hana/pom.xml
index 7b4880994..1bbc036c2 100644
--- a/composites/ebean-hana/pom.xml
+++ b/composites/ebean-hana/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-hana
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-mariadb/pom.xml b/composites/ebean-mariadb/pom.xml
index fc6c5925c..5e6bd20d8 100644
--- a/composites/ebean-mariadb/pom.xml
+++ b/composites/ebean-mariadb/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-mariadb
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-mysql/pom.xml b/composites/ebean-mysql/pom.xml
index 602da3ceb..cac8d8a9f 100644
--- a/composites/ebean-mysql/pom.xml
+++ b/composites/ebean-mysql/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-mysql
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-nuodb/pom.xml b/composites/ebean-nuodb/pom.xml
index a58897819..1b1fb3857 100644
--- a/composites/ebean-nuodb/pom.xml
+++ b/composites/ebean-nuodb/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-nuodb
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-oracle/pom.xml b/composites/ebean-oracle/pom.xml
index dcf5b76a5..34a27740d 100644
--- a/composites/ebean-oracle/pom.xml
+++ b/composites/ebean-oracle/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-oracle
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-postgis/pom.xml b/composites/ebean-postgis/pom.xml
index 98b667668..f360523d7 100644
--- a/composites/ebean-postgis/pom.xml
+++ b/composites/ebean-postgis/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -14,7 +14,7 @@
2.5.1
- 42.6.0
+ 42.7.2
@@ -22,13 +22,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -47,19 +47,19 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-postgres
- 14.0.0
+ 14.0.1
io.ebean
ebean-postgis-types
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-postgres/pom.xml b/composites/ebean-postgres/pom.xml
index 6e23f7650..48650fbd4 100644
--- a/composites/ebean-postgres/pom.xml
+++ b/composites/ebean-postgres/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-postgres
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-sqlite/pom.xml b/composites/ebean-sqlite/pom.xml
index ac7a96dea..e8ba4b984 100644
--- a/composites/ebean-sqlite/pom.xml
+++ b/composites/ebean-sqlite/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-sqlite
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-sqlserver/pom.xml b/composites/ebean-sqlserver/pom.xml
index 4cebb6dd0..adcfe732c 100644
--- a/composites/ebean-sqlserver/pom.xml
+++ b/composites/ebean-sqlserver/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-sqlserver
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean-yugabyte/pom.xml b/composites/ebean-yugabyte/pom.xml
index 8febd2908..3ef2e2c3a 100644
--- a/composites/ebean-yugabyte/pom.xml
+++ b/composites/ebean-yugabyte/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,13 +17,13 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
@@ -42,13 +42,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-postgres
- 14.0.0
+ 14.0.1
diff --git a/composites/ebean/pom.xml b/composites/ebean/pom.xml
index e54b6ea9d..f37e439d6 100644
--- a/composites/ebean/pom.xml
+++ b/composites/ebean/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -17,31 +17,31 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
io.ebean
ebean-joda-time
- 13.24.0
+ 14.0.0
io.ebean
ebean-jackson-jsonnode
- 13.24.0
+ 14.0.0
io.ebean
ebean-jackson-mapper
- 14.0.0
+ 14.0.1
@@ -60,13 +60,13 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-all
- 14.0.0
+ 14.0.1
diff --git a/composites/pom.xml b/composites/pom.xml
index 7fb663ed6..b16cabddb 100644
--- a/composites/pom.xml
+++ b/composites/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
composites
diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml
index 93960d07d..e2020d174 100644
--- a/ebean-api/pom.xml
+++ b/ebean-api/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean api
@@ -39,7 +39,7 @@
io.avaje
avaje-config
- 3.10
+ 3.12
diff --git a/ebean-api/src/main/java/io/ebean/DataIntegrityException.java b/ebean-api/src/main/java/io/ebean/DataIntegrityException.java
index 495bdd349..c9f451ee7 100644
--- a/ebean-api/src/main/java/io/ebean/DataIntegrityException.java
+++ b/ebean-api/src/main/java/io/ebean/DataIntegrityException.java
@@ -3,7 +3,7 @@ package io.ebean;
import jakarta.persistence.PersistenceException;
/**
- * Thrown when a foreign key constraint is enforced.
+ * Thrown when a foreign key constraint is enforced or a field is too large.
*/
public class DataIntegrityException extends PersistenceException {
private static final long serialVersionUID = -6740171949170180970L;
@@ -14,4 +14,11 @@ public class DataIntegrityException extends PersistenceException {
public DataIntegrityException(String message, Throwable cause) {
super(message, cause);
}
+
+ /**
+ * Create with message only.
+ */
+ public DataIntegrityException(String message) {
+ super(message);
+ }
}
diff --git a/ebean-api/src/main/java/io/ebean/Database.java b/ebean-api/src/main/java/io/ebean/Database.java
index bb9ab9b72..f4a5b7897 100644
--- a/ebean-api/src/main/java/io/ebean/Database.java
+++ b/ebean-api/src/main/java/io/ebean/Database.java
@@ -88,16 +88,16 @@ public interface Database {
/**
* Return a new database builder.
- * {@code
- *
- * // build the 'default' database using configuration
- * // from application.properties / application.yaml
- *
- * Database db = Database.builder()
- * .loadFromProperties()
- * .build();
- *
- * }
+ * {@code
+ *
+ * // build the 'default' database using configuration
+ * // from application.properties / application.yaml
+ *
+ * Database db = Database.builder()
+ * .loadFromProperties()
+ * .build();
+ *
+ * }
*/
static DatabaseBuilder builder() {
return new DatabaseConfig();
diff --git a/ebean-api/src/main/java/io/ebean/DatabaseBuilder.java b/ebean-api/src/main/java/io/ebean/DatabaseBuilder.java
index 80ba130b1..bcd228c75 100644
--- a/ebean-api/src/main/java/io/ebean/DatabaseBuilder.java
+++ b/ebean-api/src/main/java/io/ebean/DatabaseBuilder.java
@@ -85,6 +85,7 @@ public interface DatabaseBuilder {
}
return this;
}
+
/**
* Set the name of the Database.
*/
@@ -2177,6 +2178,11 @@ public interface DatabaseBuilder {
@Deprecated
DatabaseBuilder setMetricNaming(Function metricNaming);
+ /**
+ * Sets the length check mode.
+ */
+ DatabaseConfig lengthCheck(LengthCheck lengthCheck);
+
/**
* Provides read access (getters) for the DatabaseBuilder configuration
* that has been set.
@@ -3039,5 +3045,9 @@ public interface DatabaseBuilder {
*/
Function getMetricNaming();
+ /**
+ * Returns the length check mode.
+ */
+ LengthCheck getLengthCheck();
}
}
diff --git a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java
index c689e7bda..38dc0b5f9 100644
--- a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java
+++ b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java
@@ -531,6 +531,8 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
private String dumpMetricsOptions;
+ private LengthCheck lengthCheck = LengthCheck.OFF;
+
private Function metricNaming = MetricNamingMatch.INSTANCE;
/**
@@ -2124,6 +2126,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
+ lengthCheck = p.getEnum(LengthCheck.class, "lengthCheck", lengthCheck);
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
@@ -2500,6 +2503,19 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
return this;
}
+ /**
+ * Returns the length check mode.
+ */
+ public LengthCheck getLengthCheck() {
+ return lengthCheck;
+ }
+
+ @Override
+ public DatabaseConfig lengthCheck(LengthCheck lengthCheck) {
+ this.lengthCheck = lengthCheck;
+ return this;
+ }
+
public enum UuidVersion {
VERSION4,
VERSION1,
diff --git a/ebean-api/src/main/java/io/ebean/config/LengthCheck.java b/ebean-api/src/main/java/io/ebean/config/LengthCheck.java
new file mode 100644
index 000000000..4f4abf887
--- /dev/null
+++ b/ebean-api/src/main/java/io/ebean/config/LengthCheck.java
@@ -0,0 +1,22 @@
+package io.ebean.config;
+
+/**
+ * Defines the length-check mode.
+ *
+ * @author Roland Praml, FOCONIS AG
+ */
+public enum LengthCheck {
+ /**
+ * By default, length checking is off. This means, strings/jsons and files are passed to the DB and the DB might or might not check the length.
+ * The DB has to check the data length. Note this is not possible for certain datatypes (e.g. clob without size)
+ */
+ OFF,
+ /**
+ * When enabling length check, ebean validates strings/json strings and files before saving them to DB.
+ */
+ ON,
+ /**
+ * Same as "ON", but take the UTF8-bytelength for validation. This may be useful, if you have an UTF8 based charset (default for DB2)
+ */
+ UTF8
+}
diff --git a/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java b/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java
index 458199c8e..be85d0e37 100644
--- a/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java
+++ b/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java
@@ -8,6 +8,7 @@ import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -23,7 +24,7 @@ public final class ShutdownManager {
private static final System.Logger log = EbeanVersion.log;
private static final ReentrantLock lock = new ReentrantLock();
- private static final List databases = new ArrayList<>();
+ private static final List databases = Collections.synchronizedList(new ArrayList<>());
private static final ShutdownHook shutdownHook = new ShutdownHook();
private static boolean stopping;
@@ -177,12 +178,7 @@ public final class ShutdownManager {
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerDatabase(Database server) {
- lock.lock();
- try {
- databases.add(server);
- } finally {
- lock.unlock();
- }
+ databases.add(server);
}
/**
@@ -192,12 +188,7 @@ public final class ShutdownManager {
*
*/
public static void unregisterDatabase(Database server) {
- lock.lock();
- try {
- databases.remove(server);
- } finally {
- lock.unlock();
- }
+ databases.remove(server);
}
private static class ShutdownHook extends Thread {
diff --git a/ebean-api/src/main/java/io/ebean/text/json/JsonWriteOptions.java b/ebean-api/src/main/java/io/ebean/text/json/JsonWriteOptions.java
index 7995f7a84..913ac4114 100644
--- a/ebean-api/src/main/java/io/ebean/text/json/JsonWriteOptions.java
+++ b/ebean-api/src/main/java/io/ebean/text/json/JsonWriteOptions.java
@@ -22,6 +22,8 @@ public class JsonWriteOptions {
protected JsonConfig.Include include;
+ protected boolean includeLoadedImplicit = true;
+
protected Map> visitorMap;
/**
@@ -73,6 +75,20 @@ public class JsonWriteOptions {
this.include = include;
}
+ /**
+ * Should loaded properties be included implicit, if no other fetch path is specified (default = true).
+ */
+ public boolean isIncludeLoadedImplicit() {
+ return includeLoadedImplicit;
+ }
+
+ /**
+ * Set include loaded properties implicit (default = true).
+ */
+ public void setIncludeLoadedImplicit(boolean includeLoadedImplicit) {
+ this.includeLoadedImplicit = includeLoadedImplicit;
+ }
+
/**
* Register a JsonWriteBeanVisitor for the root level.
*/
diff --git a/ebean-api/src/test/java/io/ebean/config/DatabaseConfigTest.java b/ebean-api/src/test/java/io/ebean/config/DatabaseConfigTest.java
index 63bc0f2eb..9b5afb2b0 100644
--- a/ebean-api/src/test/java/io/ebean/config/DatabaseConfigTest.java
+++ b/ebean-api/src/test/java/io/ebean/config/DatabaseConfigTest.java
@@ -75,6 +75,7 @@ class DatabaseConfigTest {
props.setProperty("defaultServer", "false");
props.setProperty("skipDataSourceCheck", "true");
props.setProperty("readOnlyDatabase", "true");
+ props.setProperty("lengthCheck", "ON");
props.setProperty("queryPlan.enable", "true");
props.setProperty("queryPlan.thresholdMicros", "10000");
@@ -95,6 +96,7 @@ class DatabaseConfigTest {
assertTrue(settings.isLoadModuleInfo());
assertTrue(settings.skipDataSourceCheck());
assertTrue(settings.readOnlyDatabase());
+ assertThat(settings.getLengthCheck()).isEqualTo(LengthCheck.ON);
assertTrue(settings.isIdGeneratorAutomatic());
assertFalse(settings.getPlatformConfig().isCaseSensitiveCollation());
@@ -128,8 +130,11 @@ class DatabaseConfigTest {
assertThat(settings.getMappingLocations()).containsExactly("classpath:/foo","bar");
- config.setPersistBatch(PersistBatch.NONE);
- config.setPersistBatchOnCascade(PersistBatch.NONE);
+ config.persistBatch(PersistBatch.NONE)
+ .persistBatchOnCascade(PersistBatch.NONE)
+ .lengthCheck(LengthCheck.ON)
+ .lengthCheck(LengthCheck.UTF8);
+
Properties props1 = new Properties();
props1.setProperty("ebean.persistBatch", "ALL");
@@ -146,6 +151,7 @@ class DatabaseConfigTest {
assertEquals(PersistBatch.ALL, settings.getPersistBatch());
assertEquals(PersistBatch.ALL, settings.getPersistBatchOnCascade());
+ assertEquals(LengthCheck.UTF8, settings.getLengthCheck());
config.setEnabledL2Regions("r0,orgs");
assertEquals("r0,orgs", settings.getEnabledL2Regions());
@@ -174,6 +180,7 @@ class DatabaseConfigTest {
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
assertEquals(10, config.getQueryPlanCaptureMaxCount());
+ assertThat(config.getLengthCheck()).isEqualTo(LengthCheck.OFF);
config.setLoadModuleInfo(false);
assertFalse(config.isAutoLoadModuleInfo());
diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml
index 001501f40..b2881bd78 100644
--- a/ebean-bom/pom.xml
+++ b/ebean-bom/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean bom
@@ -89,103 +89,103 @@
io.ebean
ebean
- 14.0.0
+ 14.0.1
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
io.ebean
ebean-core-type
- 14.0.0
+ 14.0.1
io.ebean
ebean-joda-time
- 13.24.0
+ 14.0.0
io.ebean
ebean-jackson-jsonnode
- 13.24.0
+ 14.0.0
io.ebean
ebean-jackson-mapper
- 14.0.0
+ 14.0.1
io.ebean
ebean-ddl-generator
- 14.0.0
+ 14.0.1
io.ebean
ebean-externalmapping-api
- 13.18.0
+ 14.0.0
io.ebean
ebean-externalmapping-xml
- 13.18.0
+ 14.0.0
io.ebean
ebean-autotune
- 13.18.0
+ 14.0.0
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
io.ebean
querybean-generator
- 14.0.0
+ 14.0.1
io.ebean
kotlin-querybean-generator
- 14.0.0
+ 14.0.1
io.ebean
ebean-test
- 14.0.0
+ 14.0.1
io.ebean
ebean-redis
- 14.0.0
+ 14.0.1
io.ebean
ebean-spring-txn
- 14.0.0
+ 14.0.1
@@ -193,79 +193,79 @@
io.ebean
ebean-clickhouse
- 14.0.0
+ 14.0.1
io.ebean
ebean-db2
- 14.0.0
+ 14.0.1
io.ebean
ebean-h2
- 14.0.0
+ 14.0.1
io.ebean
ebean-hana
- 14.0.0
+ 14.0.1
io.ebean
ebean-mariadb
- 14.0.0
+ 14.0.1
io.ebean
ebean-mysql
- 14.0.0
+ 14.0.1
io.ebean
ebean-nuodb
- 14.0.0
+ 14.0.1
io.ebean
ebean-oracle
- 14.0.0
+ 14.0.1
io.ebean
ebean-postgres
- 14.0.0
+ 14.0.1
io.ebean
ebean-postgis
- 14.0.0
+ 14.0.1
io.ebean
ebean-postgis-types
- 14.0.0
+ 14.0.1
io.ebean
ebean-sqlite
- 14.0.0
+ 14.0.1
io.ebean
ebean-sqlserver
- 14.0.0
+ 14.0.1
diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml
index d239a9c26..7fdfb41d0 100644
--- a/ebean-core-type/pom.xml
+++ b/ebean-core-type/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean-core-type
@@ -16,7 +16,7 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
@@ -30,7 +30,7 @@
org.postgresql
postgresql
- 42.6.0
+ 42.7.2
true
diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java b/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java
index b08bb529a..d955445b9 100644
--- a/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java
+++ b/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java
@@ -174,4 +174,9 @@ public interface DataBinder {
*/
String popJson();
+ /**
+ * Returns the last bound object (e.g. for BindValidation). Note for InputStreams you'll get an InputStreamInfo.
+ */
+ Object popLastObject();
+
}
diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/InputStreamInfo.java b/ebean-core-type/src/main/java/io/ebean/core/type/InputStreamInfo.java
new file mode 100644
index 000000000..137ab4da6
--- /dev/null
+++ b/ebean-core-type/src/main/java/io/ebean/core/type/InputStreamInfo.java
@@ -0,0 +1,27 @@
+package io.ebean.core.type;
+
+import java.io.InputStream;
+
+/**
+ * Helper to transports length info of DataBind.setBinaryStream(stream, length) to BindValidation
+ *
+ * @author Roland Praml, FOCONIS AG
+ */
+public final class InputStreamInfo {
+
+ private final InputStream stream;
+ private final long length;
+
+ public InputStreamInfo(InputStream stream, long length) {
+ this.stream = stream;
+ this.length = length;
+ }
+
+ public InputStream stream() {
+ return stream;
+ }
+
+ public long length() {
+ return length;
+ }
+}
diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml
index 4c5d16349..7612cc9e2 100644
--- a/ebean-core/pom.xml
+++ b/ebean-core/pom.xml
@@ -3,7 +3,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean-core
@@ -22,7 +22,7 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
@@ -46,7 +46,7 @@
io.ebean
ebean-core-type
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
provided
@@ -47,7 +47,7 @@
org.postgresql
postgresql
- 42.6.0
+ 42.7.2
provided
@@ -62,7 +62,7 @@
io.ebean
ebean-test
- 14.0.0
+ 14.0.1
test
diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml
index 9e3c19402..d21e44808 100644
--- a/ebean-querybean/pom.xml
+++ b/ebean-querybean/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean querybean
@@ -17,7 +17,7 @@
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
provided
@@ -63,14 +63,14 @@
io.ebean
ebean-ddl-generator
- 14.0.0
+ 14.0.1
test
io.ebean
ebean-test
- 14.0.0
+ 14.0.1
test
@@ -84,7 +84,7 @@
io.ebean
querybean-generator
- 14.0.0
+ 14.0.1
provided
diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/TQAssocBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/TQAssocBean.java
index 0d87f3612..37324dfa3 100644
--- a/ebean-querybean/src/main/java/io/ebean/typequery/TQAssocBean.java
+++ b/ebean-querybean/src/main/java/io/ebean/typequery/TQAssocBean.java
@@ -108,6 +108,18 @@ public abstract class TQAssocBean extends TQAssoc {
return fetchWithProperties(FETCH_DEFAULT, properties);
}
+
+ /**
+ * Fetch this association with config for the type of fetch and the specified properties.
+ *
+ * @param config Fetch configuration to define the type of fetch to use
+ * @param properties The properties to fetch
+ */
+ @SafeVarargs @SuppressWarnings("varargs")
+ public final R fetch(FetchConfig config, TQProperty... properties) {
+ return fetchWithProperties(config, properties);
+ }
+
/**
* Eagerly fetch this association using a 'query join' loading the specified properties.
*/
diff --git a/ebean-querybean/src/test/java/org/example/domain/Alias.java b/ebean-querybean/src/test/java/org/example/domain/Alias.java
new file mode 100644
index 000000000..9a5b38e24
--- /dev/null
+++ b/ebean-querybean/src/test/java/org/example/domain/Alias.java
@@ -0,0 +1,14 @@
+package org.example.domain;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Version;
+
+@Entity
+public class Alias {
+
+ @Id
+ long id;
+ @Version
+ long version;
+}
diff --git a/ebean-querybean/src/test/java/org/querytest/QOrderTest.java b/ebean-querybean/src/test/java/org/querytest/QOrderTest.java
index bcfa451ec..44627581d 100644
--- a/ebean-querybean/src/test/java/org/querytest/QOrderTest.java
+++ b/ebean-querybean/src/test/java/org/querytest/QOrderTest.java
@@ -1,6 +1,7 @@
package org.querytest;
import io.ebean.DB;
+import io.ebean.FetchConfig;
import io.ebean.FetchGroup;
import io.ebean.Query;
import io.ebean.test.LoggedSql;
@@ -8,6 +9,7 @@ import org.example.domain.Customer;
import org.example.domain.Order;
import org.example.domain.OrderDetail;
import org.example.domain.otherpackage.PhoneNumber;
+import org.example.domain.query.QContact;
import org.example.domain.query.QCustomer;
import org.example.domain.query.QOrder;
import org.example.domain.query.QOrderDetail;
@@ -26,10 +28,17 @@ public class QOrderTest {
private static final QOrder or = QOrder.alias();
+ private static final QContact co = QContact.alias();
+
private static final FetchGroup fgC = QCustomer.forFetchGroup()
.select(cu.name, cu.phoneNumber)
.buildFetchGroup();
+ private static final FetchGroup fgCustomerWithContacts = QCustomer.forFetchGroup()
+ .select(cu.name, cu.phoneNumber)
+ .contacts.fetch(FetchConfig.ofQuery(1000), co.firstName, co.lastName, co.email)
+ .buildFetchGroup();
+
private static final FetchGroup fgNested1 = QOrder.forFetchGroup()
.select(or.status, or.shipDate)
.customer.fetch(fgC)
@@ -70,6 +79,20 @@ public class QOrderTest {
DB.delete(customer);
}
+ @Test
+ void fetchQueryWithBatch() {
+ LoggedSql.start();
+
+ new QCustomer()
+ .select(fgCustomerWithContacts)
+ .findList();
+
+ final List sql = LoggedSql.stop();
+ assertThat(sql).hasSize(2);
+ assertThat(sql.get(0)).contains("select t0.id, t0.name, t0.phone_number from be_customer t0");
+ assertThat(sql.get(1)).contains("select t0.customer_id, t0.id, t0.first_name, t0.last_name, t0.email from be_contact t0 where");
+ }
+
@Test
public void fetchCache() {
diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml
index 350068c70..b3f711962 100644
--- a/ebean-redis/pom.xml
+++ b/ebean-redis/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean-redis
@@ -22,28 +22,28 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
provided
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
provided
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
test
io.ebean
ebean-test
- 14.0.0
+ 14.0.1
test
@@ -57,7 +57,7 @@
io.ebean
querybean-generator
- 14.0.0
+ 14.0.1
provided
diff --git a/ebean-spring-txn/pom.xml b/ebean-spring-txn/pom.xml
index 6d2d9a2c8..6cb0cda91 100644
--- a/ebean-spring-txn/pom.xml
+++ b/ebean-spring-txn/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean-spring-txn
@@ -28,7 +28,7 @@
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
provided
@@ -77,7 +77,7 @@
io.ebean
ebean-test
- 14.0.0
+ 14.0.1
test
diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml
index 6cf4553db..192631849 100644
--- a/ebean-test/pom.xml
+++ b/ebean-test/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
ebean test
@@ -33,20 +33,20 @@
io.ebean
ebean-platform-h2
- 14.0.0
+ 14.0.1
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
provided
io.ebean
ebean-ddl-generator
- 14.0.0
+ 14.0.1
@@ -135,28 +135,28 @@
io.ebean
ebean-joda-time
- 13.24.0
+ 14.0.0
test
io.ebean
ebean-jackson-jsonnode
- 13.24.0
+ 14.0.0
test
io.ebean
ebean-jackson-mapper
- 14.0.0
+ 14.0.1
test
io.ebean
ebean-platform-all
- 14.0.0
+ 14.0.1
test
@@ -213,7 +213,7 @@
org.postgresql
postgresql
- 42.6.0
+ 42.7.2
org.checkerframework
diff --git a/ebean-test/src/test/java/io/ebean/xtest/internal/server/text/json/WriteJsonDirtyTest.java b/ebean-test/src/test/java/io/ebean/xtest/internal/server/text/json/WriteJsonDirtyTest.java
index 4918a243b..f18a5cb82 100644
--- a/ebean-test/src/test/java/io/ebean/xtest/internal/server/text/json/WriteJsonDirtyTest.java
+++ b/ebean-test/src/test/java/io/ebean/xtest/internal/server/text/json/WriteJsonDirtyTest.java
@@ -43,7 +43,7 @@ public class WriteJsonDirtyTest {
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator generator = jsonFactory.createGenerator(writer);
- WriteJson writeJson = new WriteJson(server, generator, null, null, null, null);
+ WriteJson writeJson = new WriteJson(server, generator, null, null, null, null, true);
descriptor.jsonWriteDirty(writeJson, entityBean, dirtyProperties);
generator.flush();
diff --git a/ebean-test/src/test/java/org/tests/basic/TestLength.java b/ebean-test/src/test/java/org/tests/basic/TestLength.java
new file mode 100644
index 000000000..fa30635f9
--- /dev/null
+++ b/ebean-test/src/test/java/org/tests/basic/TestLength.java
@@ -0,0 +1,101 @@
+package org.tests.basic;
+
+import io.ebean.DB;
+import io.ebean.DataIntegrityException;
+import io.ebean.xtest.BaseTestCase;
+import org.junit.jupiter.api.Test;
+import org.tests.model.json.EBasicJsonList;
+import org.tests.model.json.EBasicJsonMap;
+import org.tests.model.types.SomeFileBean;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/**
+ * @author Roland Praml, FOCONIS AG
+ */
+public class TestLength extends BaseTestCase {
+
+ @Test
+ void testFileSize() throws IOException {
+ File f1 = File.createTempFile("testfile", "tmp");
+ byte[] buf = new byte[1024];
+ try (FileOutputStream fos = new FileOutputStream(f1)) {
+ for (int i = 0; i < 100; i++) {
+ fos.write(buf);
+ }
+ }
+
+ SomeFileBean sfb1 = new SomeFileBean();
+ sfb1.setContent(f1);
+ DB.save(sfb1);
+
+ try (FileOutputStream fos = new FileOutputStream(f1)) {
+ for (int i = 0; i < 101; i++) {
+ fos.write(buf);
+ }
+ }
+
+ SomeFileBean sfb2 = new SomeFileBean();
+ sfb2.setContent(f1);
+ assertThatThrownBy(() -> DB.save(sfb2)).isInstanceOf(DataIntegrityException.class);
+ }
+
+
+ /**
+ * The property 'EBasicJsonMap.content' is annotated with @DbJson(length=5000). So we assume, that we cannot save Json-objects
+ * where the serialized form exceed that limit and we would expect an error on save.
+ * The length check works for platforms like h2, as H2 uses a 'varchar(5000)'. So it is impossible to save such long jsons,
+ * but it won't work for SqlServer, as here 'nvarchar(max)' is used. No validation happens at DB level and you might get very
+ * large Json objects in your database. This mostly happens unintentionally (programming error, misconfiguration)
+ * So they are in the database and they cannot be accessed by ebean any more, because there are new limits in Jackson:
+ * - Max 5 Meg per string in 2.15.0
+ * - Max 20 Meg per string in 2.15.1
+ * see https://github.com/FasterXML/jackson-core/issues/1014
+ */
+ @Test
+ void testLongString() {
+ // s is so big, that it could not be deserialized by jackson
+ String s = new String(new char[20_000_001]).replace('\0', 'x');
+
+ EBasicJsonMap bean = new EBasicJsonMap();
+ bean.setName("b1");
+ bean.setContent(Map.of("string", s));
+
+ assertThatThrownBy(() -> {
+ // we expect, that we can NOT save the bean, this is ensured by the bind validator.
+ DB.save(bean);
+ }).isInstanceOf(DataIntegrityException.class);
+
+ }
+
+
+ /**
+ * Tests the UTF8 validation.
+ */
+ @Test
+ void testUtf8() {
+
+ String s = new String(new char[40]).replace('\0', '€');
+
+ EBasicJsonList bean = new EBasicJsonList();
+ bean.setName("b1");
+ bean.setTags(List.of(s));
+
+ if (isDb2() || isOracle()) {
+ // by default, DB2 && oracle uses bytes in varchar, so an '€' symbol needs 3 bytes
+ assertThatThrownBy(() -> {
+ // we expect, that we can NOT save the bean, this is ensured by the bind validator.
+ DB.save(bean);
+ }).isInstanceOf(DataIntegrityException.class);
+ } else {
+ DB.save(bean);
+ }
+ }
+
+}
diff --git a/ebean-test/src/test/java/org/tests/json/TestDbJsonLength.java b/ebean-test/src/test/java/org/tests/json/TestDbJsonLength.java
new file mode 100644
index 000000000..0fd9a3586
--- /dev/null
+++ b/ebean-test/src/test/java/org/tests/json/TestDbJsonLength.java
@@ -0,0 +1,52 @@
+package org.tests.json;
+
+import io.ebean.DB;
+import io.ebean.DataIntegrityException;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+import org.tests.model.json.EBasicJsonMap;
+
+import java.util.Map;
+
+class TestDbJsonLength {
+
+
+ /**
+ * The property 'EBasicJsonMap.content' is annotated with @DbJson(length=5000). So we assume, that we cannot save Json-objects
+ * where the serialized form exceed that limit and we would expect an error on save.
+ * The length check works for platforms like h2, as H2 uses a 'varchar(5000)'. So it is impossible to save such long jsons,
+ * but it won't work for SqlServer, as here 'nvarchar(max)' is used. No validation happens at DB level and you might get very
+ * large Json objects in your database. This mostly happens unintentionally (programming error, misconfiguration)
+ * So they are in the database and they cannot be accessed by ebean any more, because there are new limits in Jackson:
+ * - Max 5 Meg per string in 2.15.0
+ * - Max 20 Meg per string in 2.15.1
+ * see https://github.com/FasterXML/jackson-core/issues/1014
+ */
+ @Test
+ void testLongString() {
+ // s is so big, that it could not be deserialized by jackson
+ String s = new String(new char[20_000_001]).replace('\0', 'x');
+
+ EBasicJsonMap bean = new EBasicJsonMap();
+ bean.setName("b1");
+ bean.setContent(Map.of("string", s));
+
+ SoftAssertions softly = new SoftAssertions();
+
+ softly.assertThatThrownBy(() -> {
+ DB.save(bean);
+ }).isInstanceOf(DataIntegrityException.class);
+
+
+ if (bean.getId() != null) {
+ // we expect, that we could NOT save the bean, but this is not true for sqlServer.
+ // we will get a javax.persistence.PersistenceException: Error loading on org.tests.model.json.EBasicJsonMap.content
+ // when we try to load the bean back from DB
+ DB.find(EBasicJsonMap.class, bean.getId());
+ }
+
+ softly.assertAll();
+
+ }
+
+}
diff --git a/ebean-test/src/test/java/org/tests/json/include/TestJsonImplicitLoaded.java b/ebean-test/src/test/java/org/tests/json/include/TestJsonImplicitLoaded.java
new file mode 100644
index 000000000..f7bceef35
--- /dev/null
+++ b/ebean-test/src/test/java/org/tests/json/include/TestJsonImplicitLoaded.java
@@ -0,0 +1,36 @@
+package org.tests.json.include;
+
+import io.ebean.DB;
+import io.ebean.FetchPath;
+import io.ebean.config.JsonConfig;
+import io.ebean.text.PathProperties;
+import io.ebean.text.json.JsonWriteOptions;
+import org.junit.jupiter.api.Test;
+import org.tests.model.basic.Contact;
+import org.tests.model.basic.ResetBasicData;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class TestJsonImplicitLoaded {
+
+ @Test
+ void testToBeanToJson() {
+ ResetBasicData.reset();
+
+ FetchPath path = PathProperties.parse("*");
+ Contact bean = DB.find(Contact.class).setId(1).apply(path).findOne();
+
+ JsonWriteOptions options = new JsonWriteOptions();
+ options.setInclude(JsonConfig.Include.NON_NULL);
+ options.setPathProperties(path);
+ options.setIncludeLoadedImplicit(false);
+
+ String asJson = DB.json().toJson(bean, options);
+ assertThat(asJson).contains("customer\":{\"id\":1}"); // hold only ID
+
+ bean.getCustomer().getName(); // lazy-load bean;
+ asJson = DB.json().toJson(bean, options);
+ assertThat(asJson).contains("customer\":{\"id\":1}"); // expect the same result
+ }
+
+}
diff --git a/ebean-test/src/test/java/org/tests/model/json/EBasicJsonMap.java b/ebean-test/src/test/java/org/tests/model/json/EBasicJsonMap.java
index 351265f61..5feacf71c 100644
--- a/ebean-test/src/test/java/org/tests/model/json/EBasicJsonMap.java
+++ b/ebean-test/src/test/java/org/tests/model/json/EBasicJsonMap.java
@@ -18,7 +18,7 @@ public class EBasicJsonMap {
String name;
- @DbJson
+ @DbJson(length = 5000)
Map content;
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
diff --git a/ebean-test/src/test/java/org/tests/model/types/SomeFileBean.java b/ebean-test/src/test/java/org/tests/model/types/SomeFileBean.java
index eb5f8543b..fa6fa03be 100644
--- a/ebean-test/src/test/java/org/tests/model/types/SomeFileBean.java
+++ b/ebean-test/src/test/java/org/tests/model/types/SomeFileBean.java
@@ -1,9 +1,7 @@
package org.tests.model.types;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Lob;
-import jakarta.persistence.Version;
+import jakarta.persistence.*;
+
import java.io.File;
@Entity
@@ -18,6 +16,7 @@ public class SomeFileBean {
String name;
@Lob
+ @Column(length = 100 * 1024) // limit to 100kb
File content;
public Long getId() {
diff --git a/ebean-test/src/test/resources/ebean.properties b/ebean-test/src/test/resources/ebean.properties
index 9dec823ee..6bd984585 100644
--- a/ebean-test/src/test/resources/ebean.properties
+++ b/ebean-test/src/test/resources/ebean.properties
@@ -157,6 +157,7 @@ datasource.oracle.url=jdbc:oracle:thin:@localhost:1521:XE
## set this to use timestamp rather than timestamptz
#ebean.postgres.timestamp=timestamp
+ebean.pg.lengthCheck=on
datasource.pg.username=unit
datasource.pg.password=test
datasource.pg.url=jdbc:postgresql://127.0.0.1:6432/unit
diff --git a/ebean-test/testconfig/ebean-cockroach.properties b/ebean-test/testconfig/ebean-cockroach.properties
index 604387b76..f088b3260 100644
--- a/ebean-test/testconfig/ebean-cockroach.properties
+++ b/ebean-test/testconfig/ebean-cockroach.properties
@@ -2,4 +2,4 @@ ebean.test.platform=cockroach
ebean.test.dbName=unit
datasource.default=cockroach
#ebean.test.cockroach.version=v21.2.6
-
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-db2.properties b/ebean-test/testconfig/ebean-db2.properties
index 4ffab60f1..23006ac4b 100644
--- a/ebean-test/testconfig/ebean-db2.properties
+++ b/ebean-test/testconfig/ebean-db2.properties
@@ -5,3 +5,4 @@ ebean.test.username=admin
ebean.test.password=admin
datasource.default=db2-11
ebean.db2-11.databasePlatformName=db2luw
+ebean.lengthCheck=utf8
diff --git a/ebean-test/testconfig/ebean-mariadb-10.3.properties b/ebean-test/testconfig/ebean-mariadb-10.3.properties
index 082b4dbce..b7cac9c99 100644
--- a/ebean-test/testconfig/ebean-mariadb-10.3.properties
+++ b/ebean-test/testconfig/ebean-mariadb-10.3.properties
@@ -6,3 +6,4 @@ ebean.test.mariadb.version=10.3
ebean.test.mariadb.containerName=ut_mariadb-10-3
ebean.test.mariadb.port=14308
datasource.default=mariadb-103
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-mariadb.properties b/ebean-test/testconfig/ebean-mariadb.properties
index a579e32bf..a56efb6dd 100644
--- a/ebean-test/testconfig/ebean-mariadb.properties
+++ b/ebean-test/testconfig/ebean-mariadb.properties
@@ -4,3 +4,4 @@ ebean.test.mariadb.version=10.6
ebean.test.mariadb.containerName=ut_mariadb-10-6
ebean.test.mariadb.port=14307
datasource.default=mariadb-106
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-mysql.properties b/ebean-test/testconfig/ebean-mysql.properties
index 9539946a9..5da13cb2f 100644
--- a/ebean-test/testconfig/ebean-mysql.properties
+++ b/ebean-test/testconfig/ebean-mysql.properties
@@ -4,3 +4,4 @@ ebean.test.dbName=test_ebean
# note: do not conflict with mariadb port
#ebean.test.mysql.port=4306
datasource.default=mysql-docker
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-oracle.properties b/ebean-test/testconfig/ebean-oracle.properties
index 32b3af249..388c2ec82 100644
--- a/ebean-test/testconfig/ebean-oracle.properties
+++ b/ebean-test/testconfig/ebean-oracle.properties
@@ -1,3 +1,4 @@
ebean.test.platform=oracle
ebean.test.dbName=test_eb
datasource.default=oracle
+ebean.lengthCheck=utf8
diff --git a/ebean-test/testconfig/ebean-postgres.properties b/ebean-test/testconfig/ebean-postgres.properties
index 35a8bbbda..f87670982 100644
--- a/ebean-test/testconfig/ebean-postgres.properties
+++ b/ebean-test/testconfig/ebean-postgres.properties
@@ -2,4 +2,4 @@ ebean.test.platform=postgres
datasource.default=postgres
ebean.test.dbName=unit
ebean.test.postgres.version=15
-
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-sqlserver17.properties b/ebean-test/testconfig/ebean-sqlserver17.properties
index 103b1fea2..25520ae8b 100644
--- a/ebean-test/testconfig/ebean-sqlserver17.properties
+++ b/ebean-test/testconfig/ebean-sqlserver17.properties
@@ -8,3 +8,4 @@ ebean.test.sqlserver.url=jdbc:sqlserver://localhost:9435;databaseName=test_ebean
datasource.default=sqlserver2017
ebean.sqlserver2017.databasePlatformName=sqlserver17
+ebean.lengthCheck=on
diff --git a/ebean-test/testconfig/ebean-sqlserver19.properties b/ebean-test/testconfig/ebean-sqlserver19.properties
index 80ffe7320..478bff787 100644
--- a/ebean-test/testconfig/ebean-sqlserver19.properties
+++ b/ebean-test/testconfig/ebean-sqlserver19.properties
@@ -7,6 +7,7 @@ ebean.test.sqlserver.port=9434
ebean.test.sqlserver.url=jdbc:sqlserver://localhost:9434;databaseName=test_ebean;sendTimeAsDateTime=false;integratedSecurity=false;trustServerCertificate=true
datasource.default=sqlserver2019
ebean.sqlserver2019.databasePlatformName=sqlserver17
+ebean.lengthCheck=on
## A case sensitive collation example:
#ebean.test.sqlserver.collation=LATIN1_GENERAL_100_CI_AS_SC_UTF8
diff --git a/ebean-test/testconfig/ebean-yugabyte.properties b/ebean-test/testconfig/ebean-yugabyte.properties
index 2b8e462cc..f5befb1ac 100644
--- a/ebean-test/testconfig/ebean-yugabyte.properties
+++ b/ebean-test/testconfig/ebean-yugabyte.properties
@@ -2,4 +2,4 @@ ebean.test.platform=yugabyte
datasource.default=yugabyte
ebean.test.dbName=unit
ebean.test.yugabyte.version=2.18.0.0-b65
-
+ebean.lengthCheck=on
diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml
index 5e74ad518..23f0e470f 100644
--- a/kotlin-querybean-generator/pom.xml
+++ b/kotlin-querybean-generator/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
kotlin querybean generator
@@ -21,7 +21,7 @@
io.ebean
ebean-querybean
- 14.0.0
+ 14.0.1
test
@@ -35,7 +35,7 @@
io.ebean
ebean-core
- 14.0.0
+ 14.0.1
test
@@ -56,14 +56,14 @@
io.ebean
ebean-platform-h2
- 14.0.0
+ 14.0.1
test
io.ebean
ebean-ddl-generator
- 14.0.0
+ 14.0.1
test
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Constants.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Constants.java
index d1e536221..5d7938458 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Constants.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Constants.java
@@ -2,9 +2,8 @@ package io.ebean.querybean.generator;
interface Constants {
- String AT_GENERATED = "@Generated(\"io.ebean.querybean.kotlin-generator\")";
- String AT_TYPEQUERYBEAN = "@TypeQueryBean(\"v1\")";
- String GENERATED = "io.ebean.typequery.Generated";
+ String AT_GENERATED = "@io.ebean.typequery.Generated(\"io.ebean.querybean.kotlin-generator\")";
+ String AT_TYPEQUERYBEAN = "@io.ebean.typequery.TypeQueryBean(\"v1\")";
String MAPPED_SUPERCLASS = "jakarta.persistence.MappedSuperclass";
String DISCRIMINATOR_VALUE = "jakarta.persistence.DiscriminatorValue";
@@ -19,16 +18,9 @@ interface Constants {
String DBJSONB = "io.ebean.annotation.DbJsonB";
String DBNAME = "io.ebean.annotation.DbName";
- String TQROOTBEAN = "io.ebean.typequery.TQRootBean";
String TQASSOC = "io.ebean.typequery.TQAssoc";
String TQASSOCBEAN = "io.ebean.typequery.TQAssocBean";
String TQPROPERTY = "io.ebean.typequery.TQProperty";
- String TYPEQUERYBEAN = "io.ebean.typequery.TypeQueryBean";
- String DATABASE = "io.ebean.Database";
- String DB = "io.ebean.DB";
- String FETCHGROUP = "io.ebean.FetchGroup";
- String QUERY = "io.ebean.Query";
- String TRANSACTION = "io.ebean.Transaction";
String MODULEINFO = "io.ebean.config.ModuleInfo";
String METAINF_MANIFEST = "META-INF/ebean-generated-info.mf";
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/KotlinLangAdapter.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/KotlinLangAdapter.java
index d92383e97..245a07ac8 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/KotlinLangAdapter.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/KotlinLangAdapter.java
@@ -3,17 +3,7 @@ package io.ebean.querybean.generator;
class KotlinLangAdapter implements LangAdapter {
@Override
- public void beginClass(Append writer, String shortName) {
- writer.append("class Q%s : TQRootBean<%1$s, Q%1$s> {", shortName).eol();
- }
-
- @Override
- public void beginAssocClass(Append writer, String shortName, String origShortName) {
-// writer.append("class Q%s : TQAssocBean<%s,R> {", shortName, origShortName).eol();
- }
-
- @Override
- public void alias(Append writer, String shortName) {
+ public void alias(Append writer, String shortName, String fullName) {
writer.append(" companion object {").eol();
writer.append(" /**").eol();
writer.append(" * shared 'Alias' instance used to provide").eol();
@@ -25,7 +15,7 @@ class KotlinLangAdapter implements LangAdapter {
writer.append(" * Return a query bean used to build a FetchGroup.").eol();
writer.append(" */").eol();
writer.append(" fun forFetchGroup(): Q%s {", shortName).eol();
- writer.append(" return Q%s(FetchGroup.queryFor(%s::class.java));", shortName, shortName).eol();
+ writer.append(" return Q%s(io.ebean.FetchGroup.queryFor(%s::class.java));", shortName, fullName).eol();
writer.append(" }").eol();
writer.append(" }").eol().eol();
}
@@ -59,31 +49,31 @@ class KotlinLangAdapter implements LangAdapter {
}
@Override
- public void rootBeanConstructor(Append writer, String shortName, String dbName) {
+ public void rootBeanConstructor(Append writer, String shortName, String dbName, String fullName) {
String name = (dbName == null) ? "default" : dbName;
writer.append(" /**").eol();
writer.append(" * Construct using the %s Database.", name).eol();
writer.append(" */").eol();
if (dbName == null) {
- writer.append(" constructor() : super(%s::class.java)", shortName).eol().eol();
+ writer.append(" constructor() : super(%s::class.java)", fullName).eol().eol();
} else {
- writer.append(" constructor() : super(%s::class.java, DB.byName(\"%s\"))", shortName, dbName).eol().eol();
+ writer.append(" constructor() : super(%s::class.java, io.ebean.DB.byName(\"%s\"))", fullName, dbName).eol().eol();
}
writer.append(" /**").eol();
writer.append(" * Construct with a given Transaction.", name).eol();
writer.append(" */").eol();
if (dbName == null) {
- writer.append(" constructor(transaction: Transaction) : super(%s::class.java, transaction)", shortName).eol().eol();
+ writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, transaction)", fullName).eol().eol();
} else {
- writer.append(" constructor(transaction: Transaction) : super(%s::class.java, DB.byName(\"%s\"), transaction)", shortName, dbName).eol().eol();
+ writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, io.ebean.DB.byName(\"%s\"), transaction)", fullName, dbName).eol().eol();
}
writer.eol();
writer.append(" /**").eol();
writer.append(" * Construct with a given Database.").eol();
writer.append(" */").eol();
- writer.append(" constructor(database: Database) : super(%s::class.java, database)", shortName).eol().eol();
+ writer.append(" constructor(database: io.ebean.Database) : super(%s::class.java, database)", fullName).eol().eol();
writer.append(" /**").eol();
writer.append(" * Construct for Alias.").eol();
@@ -93,7 +83,7 @@ class KotlinLangAdapter implements LangAdapter {
writer.append(" /**").eol();
writer.append(" * Private constructor for FetchGroup building.").eol();
writer.append(" */").eol();
- writer.append(" private constructor(fetchGroupQuery: Query<%s>) : super(fetchGroupQuery)", shortName).eol();
+ writer.append(" private constructor(fetchGroupQuery: io.ebean.Query<%s>) : super(fetchGroupQuery)", fullName).eol();
writer.eol();
writer.append(" /** Return a copy of the query. */").eol();
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/LangAdapter.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/LangAdapter.java
index 3c7dba065..9bb48e39d 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/LangAdapter.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/LangAdapter.java
@@ -2,13 +2,10 @@ package io.ebean.querybean.generator;
public interface LangAdapter {
- void beginClass(Append writer, String shortName);
- void beginAssocClass(Append writer, String shortName, String origShortName);
+ void alias(Append writer, String shortName, String beanFullName);
- void alias(Append writer, String shortName);
-
- void rootBeanConstructor(Append writer, String shortName, String dbName);
+ void rootBeanConstructor(Append writer, String shortName, String dbName, String beanFullName);
void assocBeanConstructor(Append writer, String shortName);
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleModuleInfoWriter.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleModuleInfoWriter.java
index a3a68f74a..fd4f92438 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleModuleInfoWriter.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleModuleInfoWriter.java
@@ -91,7 +91,6 @@ class SimpleModuleInfoWriter {
writer.append("import java.util.ArrayList;").eol();
writer.append("import java.util.Collections;").eol();
writer.append("import java.util.List;").eol();
- writer.append("import %s;", Constants.GENERATED).eol();
writer.eol();
writer.append("import io.ebean.config.ModuleInfo;").eol();
writer.append("import io.ebean.config.EntityClassRegister;").eol();
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
index 01b398fe3..9bc4edbfa 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
@@ -123,22 +123,11 @@ class SimpleQueryBeanWriter {
}
private void gatherPropertyDetails() {
- importTypes.add(Constants.GENERATED);
- importTypes.add(beanFullName);
- importTypes.add(Constants.TQROOTBEAN);
- importTypes.add(Constants.TYPEQUERYBEAN);
- importTypes.add(Constants.DATABASE);
- importTypes.add(Constants.FETCHGROUP);
- importTypes.add(Constants.QUERY);
- importTypes.add(Constants.TRANSACTION);
if (implementsInterface != null) {
implementsInterfaceFullName = implementsInterface.getQualifiedName().toString();
boolean nested = implementsInterface.getNestingKind().isNested();
implementsInterfaceShortName = Util.shortName(nested, implementsInterfaceFullName);
}
- if (dbName != null) {
- importTypes.add(Constants.DB);
- }
addClassProperties();
}
@@ -230,12 +219,6 @@ class SimpleQueryBeanWriter {
* Prepare the imports for writing assoc bean.
*/
private void prepareAssocBeanImports() {
-
- importTypes.remove(Constants.DB);
- importTypes.remove(Constants.TQROOTBEAN);
- importTypes.remove(Constants.DATABASE);
- importTypes.remove(Constants.FETCHGROUP);
- importTypes.remove(Constants.QUERY);
if (embeddable) {
importTypes.add(Constants.TQASSOC);
} else {
@@ -266,7 +249,6 @@ class SimpleQueryBeanWriter {
* Write constructors.
*/
private void writeConstructors() {
-
if (writingAssocBean) {
writeAssocBeanFetch();
writeAssocBeanConstructor();
@@ -279,7 +261,7 @@ class SimpleQueryBeanWriter {
* Write the constructors for 'root' type query bean.
*/
private void writeRootBeanConstructor() {
- lang().rootBeanConstructor(writer, shortName, dbName);
+ lang().rootBeanConstructor(writer, shortName, dbName, beanFullName);
}
private void writeAssocBeanFetch() {
@@ -315,7 +297,6 @@ class SimpleQueryBeanWriter {
* Write constructor for 'assoc' type query bean.
*/
private void writeAssocBeanConstructor() {
-
lang().assocBeanConstructor(writer, shortName);
}
@@ -344,11 +325,10 @@ class SimpleQueryBeanWriter {
writer.append(Constants.AT_GENERATED).eol();
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
if (embeddable) {
- writer.append("class Q%s : TQAssoc<%s,R> {", shortName, shortInnerName).eol();
+ writer.append("class Q%s : TQAssoc<%s,R> {", shortName, beanFullName).eol();
} else {
- writer.append("class Q%s : TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName, origShortName).eol();
+ writer.append("class Q%s : TQAssocBean<%s,R,Q%s> {", shortName, beanFullName, origShortName).eol();
}
-
} else {
writer.append("/**").eol();
writer.append(" * Query bean for %s.", shortName).eol();
@@ -357,7 +337,7 @@ class SimpleQueryBeanWriter {
writer.append(" */").eol();
writer.append(Constants.AT_GENERATED).eol();
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
- lang().beginClass(writer, shortName);
+ writer.append("class Q%s : io.ebean.typequery.TQRootBean<%s, Q%s> {", shortName, beanFullName, shortName).eol();
}
writer.eol();
@@ -365,7 +345,7 @@ class SimpleQueryBeanWriter {
private void writeAlias() {
if (!writingAssocBean) {
- lang().alias(writer, shortName);
+ lang().alias(writer, shortName, beanFullName);
}
}
diff --git a/platforms/all/pom.xml b/platforms/all/pom.xml
index 4b78c275d..ad48fd2d3 100644
--- a/platforms/all/pom.xml
+++ b/platforms/all/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -15,67 +15,67 @@
io.ebean
ebean-platform-h2
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-clickhouse
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-db2
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-hana
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-hsqldb
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-mysql
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-mariadb
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-nuodb
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-oracle
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-postgres
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-sqlanywhere
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-sqlite
- 14.0.0
+ 14.0.1
io.ebean
ebean-platform-sqlserver
- 14.0.0
+ 14.0.1
diff --git a/platforms/clickhouse/pom.xml b/platforms/clickhouse/pom.xml
index ea6471ece..ad911aefc 100644
--- a/platforms/clickhouse/pom.xml
+++ b/platforms/clickhouse/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -15,7 +15,7 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
diff --git a/platforms/db2/pom.xml b/platforms/db2/pom.xml
index 195b5dc40..5cd12a9d3 100644
--- a/platforms/db2/pom.xml
+++ b/platforms/db2/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -15,7 +15,7 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
diff --git a/platforms/h2/pom.xml b/platforms/h2/pom.xml
index da4ce9fb5..9dccef1a2 100644
--- a/platforms/h2/pom.xml
+++ b/platforms/h2/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 14.0.0
+ 14.0.1
../..
@@ -15,7 +15,7 @@
io.ebean
ebean-api
- 14.0.0
+ 14.0.1
+ 14.0.0