diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index 5eac01c20..abc15fabe 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -1160,9 +1160,25 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { public boolean isLob() { return lob; } - + + /** + * Returns true if this isLob() or the type will effectively map to a lob. + */ + @Override public boolean isDbLob() { - return lob || dbType == DbPlatformType.JSON && dbLength == 0; + if (lob) { + return true; + } + switch (dbType) { + case DbPlatformType.JSON: + case DbPlatformType.JSONB: + return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup + case DbPlatformType.JSONBlob: + case DbPlatformType.JSONClob: + return true; + default: + return false; + } } public static boolean isLobType(int type) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeProperty.java index 3bc4194b2..c13126858 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeProperty.java @@ -30,7 +30,7 @@ public interface STreeProperty extends ScalarDataReader { boolean isId(); /** - * Returns true, if this is a lob property. + * Returns true, if this is a lob property from db-perspective. */ boolean isDbLob(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java index d4d22908c..3d50a9377 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java @@ -78,6 +78,10 @@ interface SqlTreeNode { * Create the loader for this node. */ SqlTreeLoad createLoad(); - - default void unselectLobs() {}; + + /** + * Unselect lobs (for distinct queries on DB2 and Oracle). + */ + default void unselectLobs() { + }; } diff --git a/ebean-test/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java b/ebean-test/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java index 9bed5a1d0..f311dff3a 100644 --- a/ebean-test/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java +++ b/ebean-test/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java @@ -85,7 +85,7 @@ public class TestUuidGenerator { prop.store(os, "ebean uuid state file"); } } - + private Properties readPropertyFile() throws IOException { Properties prop = new Properties(); try (InputStream is = new FileInputStream(stateFile)) { @@ -108,7 +108,7 @@ public class TestUuidGenerator { assertThat(Long.parseLong(props.getProperty("timeStamp"))) .isCloseTo(uuid.timestamp(), within(2_000_000L)); } - + @Test public void testUuidInvalidMac() throws Exception { assertThatThrownBy(()-> UuidV1IdGenerator.getInstance(stateFile, "01-02-03-04-05")) @@ -117,8 +117,7 @@ public class TestUuidGenerator { assertThatThrownBy(()-> UuidV1IdGenerator.getInstance(stateFile, "01-02-03-04-05-GG")) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("01-02-03-04-05-gg is invalid.") - .hasRootCauseInstanceOf(NumberFormatException.class) - .hasRootCauseMessage("For input string: \"gg\""); + .hasRootCauseInstanceOf(NumberFormatException.class); assertThat(stateFile).doesNotExist(); } @@ -170,7 +169,7 @@ public class TestUuidGenerator { UUID uuid = gen.nextId(null); assertThat(uuid).isNotNull(); } - + @Test public void testMacChange() throws Exception { writePropertyFile("01-02-03-04-05", "1234", "1234"); diff --git a/ebean-test/src/test/java/org/tests/json/TestJsonMapBasic.java b/ebean-test/src/test/java/org/tests/json/TestJsonMapBasic.java index 6e7fc481b..1c1cebb43 100644 --- a/ebean-test/src/test/java/org/tests/json/TestJsonMapBasic.java +++ b/ebean-test/src/test/java/org/tests/json/TestJsonMapBasic.java @@ -7,6 +7,8 @@ import io.ebean.annotation.ForPlatform; import io.ebean.annotation.Platform; import io.ebean.test.LoggedSql; import io.ebean.text.json.EJson; + +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.tests.model.json.EBasicJsonMap; import org.tests.model.json.EBasicJsonMapDetail; @@ -21,25 +23,37 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class TestJsonMapBasic extends BaseTestCase { + private final EBasicJsonMap bean = new EBasicJsonMap();; + + @AfterEach + void cleanup() { + if (bean != null && bean.getId() != null) { + DB.delete(EBasicJsonMap.class, bean.getId()); + } + } + @Test @ForPlatform(Platform.POSTGRES) public void whereManyPredicatePg() { - EBasicJsonMap bean = new EBasicJsonMap(); bean.setName("own1"); bean.getDetails().add(new EBasicJsonMapDetail("detail1")); bean.getDetails().add(new EBasicJsonMapDetail("detail2")); DB.save(bean); - Query query1 = DB.find(EBasicJsonMap.class).fetch("details").where() - .startsWith("details.name", "detail").query(); + Query query1 = DB.find(EBasicJsonMap.class) + .fetch("details") + .where().startsWith("details.name", "detail") + .query(); query1.findList(); assertThat(query1.getGeneratedSql()).contains("select distinct on (t0.id, t1.id) "); - Query query2 = DB.find(EBasicJsonMap.class).where().startsWith("details.name", "detail").query(); + Query query2 = DB.find(EBasicJsonMap.class) + .where().startsWith("details.name", "detail") + .query(); query2.findList(); assertThat(query2.getGeneratedSql()).contains("select distinct on (t0.id) "); @@ -49,7 +63,6 @@ public class TestJsonMapBasic extends BaseTestCase { @ForPlatform(Platform.DB2) public void whereManyPredicateDb2() { - EBasicJsonMap bean = new EBasicJsonMap(); Map m1 = new HashMap<>(); m1.put("foo", "bar"); bean.setContent(m1); @@ -58,38 +71,32 @@ public class TestJsonMapBasic extends BaseTestCase { bean.getDetails().add(new EBasicJsonMapDetail("db2-detail2")); DB.save(bean); - try { - Query query1 = DB.find(EBasicJsonMap.class).select("*").fetch("details").where() - .startsWith("details.name", "db2-detail").query(); + Query query1 = DB.find(EBasicJsonMap.class).select("*").fetch("details").where() + .startsWith("details.name", "db2-detail").query(); - List lst = query1.findList(); + List lst = query1.findList(); - assertThat(query1.getGeneratedSql()).contains("select distinct t0.id, t0.name, t0.version,") - .doesNotContain("content"); - assertThat(lst).hasSize(1); - assertThat(lst.get(0).getContent()).containsEntry("foo", "bar"); + assertThat(query1.getGeneratedSql()).contains("select distinct t0.id, t0.name, t0.version,") + .doesNotContain("content"); + assertThat(lst).hasSize(1); + assertThat(lst.get(0).getContent()).containsEntry("foo", "bar"); - Query query2 = DB.find(EBasicJsonMap.class).where().startsWith("details.name", "db2-detail") - .query(); - query2.findList(); + Query query2 = DB.find(EBasicJsonMap.class).where().startsWith("details.name", "db2-detail") + .query(); + query2.findList(); + + assertThat(query2.getGeneratedSql()).contains("select distinct t0.id, t0.name, t0.version from"); - assertThat(query2.getGeneratedSql()).contains("select distinct t0.id, t0.name, t0.version from"); - } finally { - // temporär hier, sollte die ganze Testklasse aufräumen - DB.delete(bean); - } } @Test public void testInsertUpdateDelete() throws IOException { String s0 = "{\"docId\":18,\"contentId\":\"asd\",\"active\":true,\"contentType\":\"pg-hello\",\"content\":{\"name\":\"rob\",\"age\":45}}"; - // String s1 = - // "{\"docId\":19,\"contentId\":\"asd\",\"active\":true,\"contentType\":\"pg-hello\",\"content\":{\"name\":\"rob\",\"age\":45}}"; + //String s1 = "{\"docId\":19,\"contentId\":\"asd\",\"active\":true,\"contentType\":\"pg-hello\",\"content\":{\"name\":\"rob\",\"age\":45}}"; Map content = EJson.parseObject(s0); - EBasicJsonMap bean = new EBasicJsonMap(); bean.setName("one"); bean.setContent(content); @@ -137,7 +144,6 @@ public class TestJsonMapBasic extends BaseTestCase { String s0 = "{\"docId\":22,\"contentId\":\"initialDoc\"}"; Map content = EJson.parseObject(s0); - EBasicJsonMap bean = new EBasicJsonMap(); bean.setName("one"); bean.setContent(content); @@ -148,7 +154,10 @@ public class TestJsonMapBasic extends BaseTestCase { LoggedSql.start(); - final int rows = DB.update(EBasicJsonMap.class).set("content", content1).where().eq("id", bean.getId()).update(); + final int rows = DB.update(EBasicJsonMap.class) + .set("content", content1) + .where().eq("id", bean.getId()) + .update(); final List sql = LoggedSql.stop(); @@ -161,6 +170,5 @@ public class TestJsonMapBasic extends BaseTestCase { assertThat(content2.get("contentId")).isEqualTo("updatedDoc222"); assertThat(content2.get("docId")).isEqualTo(222L); - DB.delete(found); } }