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 0000000000..0e35e1f563 --- /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/model/json/EBasicJsonMap.java b/ebean-test/src/test/java/org/tests/model/json/EBasicJsonMap.java index 30e0f502f1..3155873126 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/pom.xml b/pom.xml index dc94a90d95..474d00dec2 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ true true false - 2.15.0 + 2.15.2 2.1.214 3.0 3.0