From bb8f3831b82ec2b593e15b2a387ac54dba004837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kli=C4=8Dka?= Date: Wed, 29 Jun 2022 16:00:52 +0200 Subject: [PATCH 01/35] Testcase demonstrating stateless update resulting in a delete --- ...anyStatelessUpdateResultsInSoftDelete.java | 78 +++++++++++++++++++ .../java/org/tests/o2m/dm/GoodsEntity.java | 32 ++++++++ .../java/org/tests/o2m/dm/WorkflowEntity.java | 44 +++++++++++ .../tests/o2m/dm/WorkflowOperationEntity.java | 45 +++++++++++ 4 files changed, 199 insertions(+) create mode 100644 ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java create mode 100644 ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java create mode 100644 ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java create mode 100644 ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java diff --git a/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java new file mode 100644 index 000000000..f12b6b3c5 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java @@ -0,0 +1,78 @@ +package org.tests.o2m; + +import io.ebean.DB; +import io.ebean.test.LoggedSql; +import io.ebean.xtest.BaseTestCase; +import org.junit.jupiter.api.Test; +import org.tests.o2m.dm.GoodsEntity; +import org.tests.o2m.dm.WorkflowEntity; +import org.tests.o2m.dm.WorkflowOperationEntity; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCase { + @Test + public void testStatelessUpdate() { + LoggedSql.start(); + var goods = new GoodsEntity(); + var workflow = new WorkflowEntity(); + var operation1 = new WorkflowOperationEntity(); + goods.setWorkflowEntity(workflow); + workflow.setOperations(List.of(operation1)); + + DB.save(goods); + + var dbGoods = DB.find(GoodsEntity.class).findOne(); + // sanity check asserts + assertThat(dbGoods.getId()).isEqualTo(1L); + assertThat(dbGoods.getWorkflowEntity().getId()).isEqualTo(1L); + assertThat(dbGoods.getWorkflowEntity().getOperations()).hasSize(1); + assertThat(dbGoods.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(1L); + + List createSql = LoggedSql.stop(); + LoggedSql.start(); + + // statelessly add another operation to the workflow and save goods + var goodsStateless = new GoodsEntity(); + goodsStateless.setId(1L); + var workflowStateless = new WorkflowEntity(); + workflowStateless.setId(1L); + var operation1Stateless = new WorkflowOperationEntity(); + operation1Stateless.setId(1L); + var operation2 = new WorkflowOperationEntity(); + goodsStateless.setWorkflowEntity(workflowStateless); + workflowStateless.setOperations(List.of(operation1Stateless, operation2)); + + + /* + - this update generates following statements + 1 txn[] delete from workflow_operation_entity where workflow_id=? + 2 txn[] -- bind(1) + 3 txn[] update workflow_entity set when_modified=? where id=? + 4 txn[] -- bind(2022-06-29 15:43:55.573,1) + 5 txn[] update workflow_operation_entity set deleted=true where workflow_id = ? and not ( id in (?) ) + 6 txn[] -- bind(1, Array[1]={1}) + 7 txn[] insert into workflow_operation_entity (name, version, when_created, when_modified, deleted, workflow_id) values (?,?,?,?,?,?) + 8 txn[] -- bind(null,1,2022-06-29 15:43:55.584,2022-06-29 15:43:55.584,false,1) + 9 txn[] update goods_entity set when_modified=?, workflow_entity_id=? where id=?; -- bind(2022-06-29 15:43:55.573,1,1) + + - number 1 is wrong + - no delete should be issued + - even if it was issued, it should have been soft delete + - the DB.update will throw exception if there is one-to-many relation on workflow_operation_entity + - it would still be referenced from other table + */ + DB.update(goodsStateless); + var updateSql = LoggedSql.stop(); + updateSql.forEach(System.out::println); + + var dbGoodsAfterUpdate = DB.find(GoodsEntity.class).findOne(); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).hasSize(2); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(1L); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(1).getId()).isEqualTo(2L); + updateSql.forEach(sql -> assertThat(sql).doesNotContain("delete from workflow_entity")); + } + +} diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java new file mode 100644 index 000000000..ea8b88b49 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java @@ -0,0 +1,32 @@ +package org.tests.o2m.dm; + +import org.tests.model.draftable.BaseDomain; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class GoodsEntity extends BaseDomain { + private String name; + + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + private WorkflowEntity workflowEntity; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public WorkflowEntity getWorkflowEntity() { + return workflowEntity; + } + + public void setWorkflowEntity(WorkflowEntity workflowEntity) { + this.workflowEntity = workflowEntity; + } +} diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java new file mode 100644 index 000000000..8ad958297 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java @@ -0,0 +1,44 @@ +package org.tests.o2m.dm; + +import io.ebean.annotation.SoftDelete; +import org.tests.model.draftable.BaseDomain; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +public class WorkflowEntity extends BaseDomain { + private String revision; + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "workflow_id") + private List operations = new ArrayList<>(); + + @SoftDelete + private boolean deleted; + + public String getRevision() { + return revision; + } + + public void setRevision(String revision) { + this.revision = revision; + } + + public List getOperations() { + return operations; + } + + public void setOperations(List operations) { + this.operations = operations; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } +} diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java new file mode 100644 index 000000000..83d228bd7 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java @@ -0,0 +1,45 @@ +package org.tests.o2m.dm; + +import io.ebean.annotation.SoftDelete; +import org.tests.model.draftable.BaseDomain; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +public class WorkflowOperationEntity extends BaseDomain { + + private String name; + + @ManyToOne + @JoinColumn(name = "workflow_id") + private WorkflowEntity workflowEntity; + + @SoftDelete + private boolean deleted; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public WorkflowEntity getWorkflowEntity() { + return workflowEntity; + } + + public void setWorkflowEntity(WorkflowEntity workflowEntity) { + this.workflowEntity = workflowEntity; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } +} From 6392f90f324265354c2ae89490f1177eff5fc4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kli=C4=8Dka?= Date: Wed, 29 Jun 2022 18:41:19 +0200 Subject: [PATCH 02/35] Add more failing test cases --- ...anyStatelessUpdateResultsInSoftDelete.java | 106 ++++++++++++++++-- 1 file changed, 94 insertions(+), 12 deletions(-) diff --git a/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java index f12b6b3c5..aac8004a7 100644 --- a/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java +++ b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java @@ -14,7 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCase { @Test - public void testStatelessUpdate() { + public void testStatelessUpdateShouldntDelete() { LoggedSql.start(); var goods = new GoodsEntity(); var workflow = new WorkflowEntity(); @@ -24,23 +24,16 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas DB.save(goods); - var dbGoods = DB.find(GoodsEntity.class).findOne(); - // sanity check asserts - assertThat(dbGoods.getId()).isEqualTo(1L); - assertThat(dbGoods.getWorkflowEntity().getId()).isEqualTo(1L); - assertThat(dbGoods.getWorkflowEntity().getOperations()).hasSize(1); - assertThat(dbGoods.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(1L); - List createSql = LoggedSql.stop(); LoggedSql.start(); // statelessly add another operation to the workflow and save goods var goodsStateless = new GoodsEntity(); - goodsStateless.setId(1L); + goodsStateless.setId(goods.getId()); var workflowStateless = new WorkflowEntity(); - workflowStateless.setId(1L); + workflowStateless.setId(workflow.getId()); var operation1Stateless = new WorkflowOperationEntity(); - operation1Stateless.setId(1L); + operation1Stateless.setId(operation1.getId()); var operation2 = new WorkflowOperationEntity(); goodsStateless.setWorkflowEntity(workflowStateless); workflowStateless.setOperations(List.of(operation1Stateless, operation2)); @@ -68,11 +61,100 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas var updateSql = LoggedSql.stop(); updateSql.forEach(System.out::println); - var dbGoodsAfterUpdate = DB.find(GoodsEntity.class).findOne(); + var dbGoodsAfterUpdate = DB.find(GoodsEntity.class, goods.getId()); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).hasSize(2); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(1L); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(1).getId()).isEqualTo(2L); updateSql.forEach(sql -> assertThat(sql).doesNotContain("delete from workflow_entity")); } + // same as previous but DB.update throws exception + @Test + public void testStatelessUpdateShouldntDeleteThrows() { + LoggedSql.start(); + var goods = new GoodsEntity(); + goods.setName("ver1"); + var workflow = new WorkflowEntity(); + workflow.setRevision("ver1"); + var operation1 = new WorkflowOperationEntity(); + operation1.setName("ver1"); + goods.setWorkflowEntity(workflow); + workflow.setOperations(List.of(operation1)); + + DB.save(goods); + + List createSql = LoggedSql.stop(); + LoggedSql.start(); + + // statelessly add another operation to the workflow and save goods + var goodsStateless = new GoodsEntity(); + goodsStateless.setId(goods.getId()); + goodsStateless.setName("ver2"); + var workflowStateless = new WorkflowEntity(); + workflowStateless.setRevision("ver2"); + workflowStateless.setId(workflow.getId()); + var operation1Stateless = new WorkflowOperationEntity(); + operation1Stateless.setName("ver2"); + operation1Stateless.setId(operation1.getId()); + var operation2 = new WorkflowOperationEntity(); + operation2.setName("ver2"); + goodsStateless.setWorkflowEntity(workflowStateless); + workflowStateless.setOperations(List.of(operation1Stateless, operation2)); + + + // throws + DB.update(goodsStateless); + var updateSql = LoggedSql.stop(); + updateSql.forEach(System.out::println); + var dbGoodsAfterUpdate = DB.find(GoodsEntity.class).findOne(); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).hasSize(2); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(operation1.getId()); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(1).getId()).isEqualTo(operation2.getId()); + updateSql.forEach(sql -> assertThat(sql).doesNotContain("delete from workflow_entity")); + } + + @Test + public void duplicateKeyWorkflowEntityInsertInsteadOfUpdate() { + var goods = new GoodsEntity(); + goods.setName("ver1"); + var workflow = new WorkflowEntity(); + workflow.setRevision("ver1"); + var operation1 = new WorkflowOperationEntity(); + operation1.setName("ver1"); + goods.setWorkflowEntity(workflow); + workflow.setOperations(List.of(operation1)); + + DB.save(goods); + + // delete operation + var goodsAfterInsert = DB.find(GoodsEntity.class, goods.getId()); + assertThat(goodsAfterInsert.getWorkflowEntity().getOperations()).hasSize(1); + goodsAfterInsert.getWorkflowEntity().setOperations(List.of()); + + DB.save(goodsAfterInsert); + assertThat(goodsAfterInsert.getWorkflowEntity().getOperations()).isEmpty(); + assertThat(DB.find(GoodsEntity.class, goods.getId()).getWorkflowEntity().getOperations()).isEmpty(); + + // statelessly add new operation + var goodsStateless = new GoodsEntity(); + goodsStateless.setId(goods.getId()); + + var workflowStateless = new WorkflowEntity(); + workflowStateless.setId(workflow.getId()); + goodsStateless.setWorkflowEntity(workflowStateless); + + var operation2 = new WorkflowOperationEntity(); + workflowStateless.setOperations(List.of(operation2)); + + // throws + // io.ebean.DuplicateKeyException: Error when batch flush on sql: insert into workflow_entity (id, revision, version, when_created, when_modified, deleted) values (?,?,?,?,?,?) + // #1: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.WORKFLOW_ENTITY(ID) ( /* key:2 */ CAST(2 AS BIGINT), NULL, CAST(1 AS BIGINT), TIMESTAMP '2022-06-29 17:38:06.463', TIMESTAMP '2022-06-29 17:38:06.463', FALSE)"; SQL statement: + //insert into workflow_entity (id, revision, version, when_created, when_modified, deleted) values (?,?,?,?,?,?) [23505-212] + DB.save(goodsStateless); + + var ops = workflow.getOperations(); + // shouldn't contain deleted operations + assertThat(ops).hasSize(1); + assertThat(goodsStateless.getWorkflowEntity().getOperations().get(0).getId()).isNotEqualTo(operation1.getId()); + } } From d20d276d56c5a6b2f7f52b3aeea35ed0de9f304a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 4 Jul 2022 12:22:27 +1200 Subject: [PATCH 03/35] #2728 - Fix for stateless update with orphanRemoval=true and softDelete --- .../server/persist/SaveManyBeans.java | 8 +++- ...anyStatelessUpdateResultsInSoftDelete.java | 40 ++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java index 1d1008765..7b7c2d970 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java @@ -126,7 +126,7 @@ final class SaveManyBeans extends SaveManyBase { // performance optimisation for large collections targetDescriptor.preAllocateIds(collection.size()); } - if (!insertedParent && many.isOrphanRemoval() && request.isForcedUpdate()) { + if (forcedUpdateOrphanRemoval()) { // collect the Id's (to exclude from deleteManyDetails) List detailIds = collectIds(collection, targetDescriptor, isMap); // deleting missing children - children not in our collected detailIds @@ -140,6 +140,10 @@ final class SaveManyBeans extends SaveManyBase { transaction.depth(-1); } + private boolean forcedUpdateOrphanRemoval() { + return !insertedParent && many.isOrphanRemoval() && request.isForcedUpdate(); + } + private void saveAllBeans(final BeanProperty orderColumn) { Object mapKeyValue = null; boolean skipSavingThisBean; @@ -340,7 +344,7 @@ final class SaveManyBeans extends SaveManyBase { return; } if (!(value instanceof BeanCollection)) { - if (!insertedParent && cascade && isChangedProperty()) { + if (!forcedUpdateOrphanRemoval() && (!insertedParent && cascade && isChangedProperty())) { persister.addToFlushQueue(many.deleteByParentId(request.beanId(), null), transaction, 0); insertAllChildren = true; } diff --git a/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java index aac8004a7..5c5784e11 100644 --- a/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java +++ b/ebean-test/src/test/java/org/tests/o2m/TestOneToManyStatelessUpdateResultsInSoftDelete.java @@ -12,9 +12,9 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCase { +class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCase { @Test - public void testStatelessUpdateShouldntDelete() { + void testStatelessUpdateShouldntDelete() { LoggedSql.start(); var goods = new GoodsEntity(); var workflow = new WorkflowEntity(); @@ -23,9 +23,7 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas workflow.setOperations(List.of(operation1)); DB.save(goods); - - List createSql = LoggedSql.stop(); - LoggedSql.start(); + LoggedSql.collect(); // statelessly add another operation to the workflow and save goods var goodsStateless = new GoodsEntity(); @@ -38,6 +36,16 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas goodsStateless.setWorkflowEntity(workflowStateless); workflowStateless.setOperations(List.of(operation1Stateless, operation2)); + // With the fix the SQL is now: + /* + txn[1002] update workflow_entity set when_modified=? where id=? + txn[1002] -- bind(2022-07-04 11:10:54.446,1) + txn[1002] update workflow_operation_entity set deleted=true where workflow_id = ? and not ( id in (?) ) + txn[1002] -- bind(1, Array[1]={1}) + txn[1002] insert into workflow_operation_entity (name, version, when_created, when_modified, deleted, workflow_id) values (?,?,?,?,?,?) + txn[1002] -- bind(null,1,2022-07-04 11:10:54.458,2022-07-04 11:10:54.458,false,1) + txn[1002] update goods_entity set when_modified=?, workflow_entity_id=? where id=?; -- bind(2022-07-04 11:10:54.446,1,1) + */ /* - this update generates following statements @@ -59,18 +67,16 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas */ DB.update(goodsStateless); var updateSql = LoggedSql.stop(); - updateSql.forEach(System.out::println); - + //updateSql.forEach(System.out::println); var dbGoodsAfterUpdate = DB.find(GoodsEntity.class, goods.getId()); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).hasSize(2); - assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(1L); - assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(1).getId()).isEqualTo(2L); + assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).extracting("id").contains(operation1.getId(), operation2.getId()); updateSql.forEach(sql -> assertThat(sql).doesNotContain("delete from workflow_entity")); } // same as previous but DB.update throws exception @Test - public void testStatelessUpdateShouldntDeleteThrows() { + void testStatelessUpdateShouldntDeleteThrows() { LoggedSql.start(); var goods = new GoodsEntity(); goods.setName("ver1"); @@ -106,7 +112,7 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas DB.update(goodsStateless); var updateSql = LoggedSql.stop(); updateSql.forEach(System.out::println); - var dbGoodsAfterUpdate = DB.find(GoodsEntity.class).findOne(); + var dbGoodsAfterUpdate = DB.find(GoodsEntity.class, goods.getId()); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations()).hasSize(2); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(0).getId()).isEqualTo(operation1.getId()); assertThat(dbGoodsAfterUpdate.getWorkflowEntity().getOperations().get(1).getId()).isEqualTo(operation2.getId()); @@ -114,7 +120,7 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas } @Test - public void duplicateKeyWorkflowEntityInsertInsteadOfUpdate() { + void duplicateKeyWorkflowEntityInsertInsteadOfUpdate() { var goods = new GoodsEntity(); goods.setName("ver1"); var workflow = new WorkflowEntity(); @@ -135,7 +141,7 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas assertThat(goodsAfterInsert.getWorkflowEntity().getOperations()).isEmpty(); assertThat(DB.find(GoodsEntity.class, goods.getId()).getWorkflowEntity().getOperations()).isEmpty(); - // statelessly add new operation + // statelessly add new WorkflowOperationEntity var goodsStateless = new GoodsEntity(); goodsStateless.setId(goods.getId()); @@ -146,11 +152,9 @@ public class TestOneToManyStatelessUpdateResultsInSoftDelete extends BaseTestCas var operation2 = new WorkflowOperationEntity(); workflowStateless.setOperations(List.of(operation2)); - // throws - // io.ebean.DuplicateKeyException: Error when batch flush on sql: insert into workflow_entity (id, revision, version, when_created, when_modified, deleted) values (?,?,?,?,?,?) - // #1: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.WORKFLOW_ENTITY(ID) ( /* key:2 */ CAST(2 AS BIGINT), NULL, CAST(1 AS BIGINT), TIMESTAMP '2022-06-29 17:38:06.463', TIMESTAMP '2022-06-29 17:38:06.463', FALSE)"; SQL statement: - //insert into workflow_entity (id, revision, version, when_created, when_modified, deleted) values (?,?,?,?,?,?) [23505-212] - DB.save(goodsStateless); + // Using save() throws io.ebean.DuplicateKeyException: Error when batch flush on sql: insert into workflow_entity ... + // Must be an update() and not save() for this to be a "stateless update" + DB.update(goodsStateless); var ops = workflow.getOperations(); // shouldn't contain deleted operations From 23d52ca192e263be2b83639b755ad0cffe074b0b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 4 Jul 2022 16:58:06 +1200 Subject: [PATCH 04/35] #2731 - Change ebean-querybean annotations from Retention RUNTIME to CLASS --- .../main/java/io/ebean/typequery/AlreadyEnhancedMarker.java | 3 +-- .../src/main/java/io/ebean/typequery/Generated.java | 2 +- .../src/main/java/io/ebean/typequery/TypeQueryBean.java | 3 +-- ebean-querybean/src/test/resources/ebean.mf | 2 ++ 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/AlreadyEnhancedMarker.java b/ebean-querybean/src/main/java/io/ebean/typequery/AlreadyEnhancedMarker.java index cc107a7bb..39340ddf8 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/AlreadyEnhancedMarker.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/AlreadyEnhancedMarker.java @@ -9,10 +9,9 @@ import java.lang.annotation.Target; * Used to denote a query bean that has already been enhanced. *

* Used by the agent to detect already enhanced type query beans to skip enhancement processing. - *

*/ @Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) +@Retention(RetentionPolicy.CLASS) public @interface AlreadyEnhancedMarker { } diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/Generated.java b/ebean-querybean/src/main/java/io/ebean/typequery/Generated.java index 918e0d1b4..92036e7eb 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/Generated.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/Generated.java @@ -11,7 +11,7 @@ import java.lang.annotation.Target; * This is code generated by the query bean generator (annotation processor). */ @Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) +@Retention(RetentionPolicy.CLASS) public @interface Generated { /** diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/TypeQueryBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/TypeQueryBean.java index d0a538ee5..10a7c7e58 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/TypeQueryBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/TypeQueryBean.java @@ -9,10 +9,9 @@ import java.lang.annotation.Target; * Used to denote a type query bean. *

* These are typically generated beans used to build queries using type safe query criteria. - *

*/ @Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) +@Retention(RetentionPolicy.CLASS) public @interface TypeQueryBean { /** diff --git a/ebean-querybean/src/test/resources/ebean.mf b/ebean-querybean/src/test/resources/ebean.mf index 5c97580de..90beca56f 100644 --- a/ebean-querybean/src/test/resources/ebean.mf +++ b/ebean-querybean/src/test/resources/ebean.mf @@ -1,2 +1,4 @@ entity-packages: org.example.domain querybean-packages: org.example.domain,org.querytest +debug: 0 +synthetic: false From 523deb20f4a81e22ded4491b75d1c3e7a13d98ad Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 4 Jul 2022 17:05:25 +1200 Subject: [PATCH 05/35] #2732 - ebean-agent - skip transactional profiling aware enhancement on query beans --- ebean-autotune/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 2 +- ebean-kotlin/pom.xml | 2 +- ebean-postgis/pom.xml | 2 +- ebean-querybean/pom.xml | 2 +- ebean-redis/pom.xml | 2 +- ebean-test/pom.xml | 2 +- pom.xml | 4 ++-- tests/test-java16/pom.xml | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index d87da836b..90e954b12 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -70,7 +70,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index dff67f11b..eab4126c8 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -98,7 +98,7 @@ - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-kotlin/pom.xml b/ebean-kotlin/pom.xml index 72fce9834..c82269ad7 100644 --- a/ebean-kotlin/pom.xml +++ b/ebean-kotlin/pom.xml @@ -92,7 +92,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index 0117b699a..e6a5d7ca8 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -104,7 +104,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index 9f531ac99..95c6ee5c0 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -107,7 +107,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index eb8a2f6c5..37d2f6cb5 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -80,7 +80,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index bf0d25236..8e25eeff3 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -266,7 +266,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 diff --git a/pom.xml b/pom.xml index cabfcd61c..246f69351 100644 --- a/pom.xml +++ b/pom.xml @@ -46,8 +46,8 @@ 13.6.0 6.1 8.0 - 13.6.4 - 13.6.4 + 13.6.5 + 13.6.5 false diff --git a/tests/test-java16/pom.xml b/tests/test-java16/pom.xml index 737e1c527..3816a644e 100644 --- a/tests/test-java16/pom.xml +++ b/tests/test-java16/pom.xml @@ -66,7 +66,7 @@ true - io.ebean.tile:enhancement:13.6.0 + io.ebean.tile:enhancement:13.6.5 From 283e0b66fa4a516d95d017ec67cb883f4da35933 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 4 Jul 2022 17:53:16 +1200 Subject: [PATCH 06/35] #2734 - maven build - excluding maven descriptor (pom and properties) from built artifacts --- ebean-api/pom.xml | 19 +++++++++++++++++++ .../src/main/java/io/ebean/EbeanVersion.java | 11 ++++++----- .../META-INF/ebean-maven-version.txt | 1 + pom.xml | 2 +- 4 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 ebean-api/src/main/resources/META-INF/ebean-maven-version.txt diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index cf4ae1bcb..fc1ccc676 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -103,4 +103,23 @@ + + + + src/main/resources + true + + **/ebean-maven-version.txt + + + + src/main/resources + false + + **/ebean-maven-version.txt + + + + + diff --git a/ebean-api/src/main/java/io/ebean/EbeanVersion.java b/ebean-api/src/main/java/io/ebean/EbeanVersion.java index c4e63efff..ec976a74e 100644 --- a/ebean-api/src/main/java/io/ebean/EbeanVersion.java +++ b/ebean-api/src/main/java/io/ebean/EbeanVersion.java @@ -3,8 +3,7 @@ package io.ebean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.Properties; /** @@ -29,9 +28,11 @@ public final class EbeanVersion { private static void readVersion() { try { - try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-api/pom.properties")) { + try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/ebean-maven-version.txt")) { if (in != null) { - version = readVersion(in); + try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(in))) { + version = reader.readLine(); + } } } log.info("ebean version: {}", version); @@ -88,7 +89,7 @@ public final class EbeanVersion { } /** - * Returns the ebean version (read from /META-INF/maven/io.ebean/ebean/pom.properties) + * Returns the ebean version (read from META-INF/ebean-maven-version.txt) */ public static String getVersion() { return version; diff --git a/ebean-api/src/main/resources/META-INF/ebean-maven-version.txt b/ebean-api/src/main/resources/META-INF/ebean-maven-version.txt new file mode 100644 index 000000000..ad96e7cf9 --- /dev/null +++ b/ebean-api/src/main/resources/META-INF/ebean-maven-version.txt @@ -0,0 +1 @@ +${project.version} diff --git a/pom.xml b/pom.xml index 246f69351..4e2418885 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.8 + 3.9 io.ebean From 745fbe883e7cf480f46424e6ec8020ea2fdee8b7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 5 Jul 2022 09:05:13 +1200 Subject: [PATCH 07/35] #2737 - Mapping of TimeZone doesn't have enough characters --- .../server/type/ScalarTypeTimeZone.java | 2 +- .../server/type/ScalarTypeTimeZoneTest.java | 15 ++++++++++++++ .../basic/type/TestExtraScalarTypes.java | 20 ++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimeZoneTest.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTimeZone.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTimeZone.java index b059d2e31..a938a1c6a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTimeZone.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTimeZone.java @@ -13,7 +13,7 @@ final class ScalarTypeTimeZone extends ScalarTypeBaseVarchar { @Override public int getLength() { - return 20; + return 32; } @Override diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimeZoneTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimeZoneTest.java new file mode 100644 index 000000000..894c20dc3 --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimeZoneTest.java @@ -0,0 +1,15 @@ +package io.ebeaninternal.server.type; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ScalarTypeTimeZoneTest { + + ScalarTypeTimeZone type = new ScalarTypeTimeZone(); + + @Test + void getLength() { + assertEquals(32, type.getLength()); + } +} diff --git a/ebean-test/src/test/java/org/tests/basic/type/TestExtraScalarTypes.java b/ebean-test/src/test/java/org/tests/basic/type/TestExtraScalarTypes.java index ff8806b25..62d3a0a59 100644 --- a/ebean-test/src/test/java/org/tests/basic/type/TestExtraScalarTypes.java +++ b/ebean-test/src/test/java/org/tests/basic/type/TestExtraScalarTypes.java @@ -16,8 +16,26 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; class TestExtraScalarTypes extends BaseTestCase { @Test - void test() { + void insertLargeTimezone() { + TimeZone tz = TimeZone.getTimeZone("America/Argentina/ComodRivadavia"); + var bean = new ESomeType(); + bean.setTimeZone(tz); + DB.save(bean); + var found = DB.find(ESomeType.class, bean.getId()); + assert found != null; + assertThat(found.getTimeZone()).isEqualTo(tz); + + var findByTimezone = DB.find(ESomeType.class).where().eq("timeZone", tz).findList(); + assertThat(findByTimezone).hasSize(1); + assertThat(findByTimezone.get(0).getId()).isEqualTo(found.getId()); + assertThat(findByTimezone.get(0).getTimeZone()).isEqualTo(tz); + + DB.delete(found); + } + + @Test + void test() { Locale locale = Locale.ENGLISH; Currency currency = Currency.getInstance(Locale.US); TimeZone tz = TimeZone.getDefault(); From 52e6c0c6255977a47ee6647d91fc5e082a8e8160 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 5 Jul 2022 10:37:55 +1200 Subject: [PATCH 08/35] #2736 - findDto nonsupport setter chain (accessor style setters, both fluid style and non fluid style) --- .../server/dto/DtoMetaBuilder.java | 17 ++- .../server/dto/DtoMetaBuilderTest.java | 84 ++++++++++-- .../io/ebean/xtest/base/DtoQuery2Test.java | 128 +++++++++++++----- 3 files changed, 178 insertions(+), 51 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java index 0632e89f2..43acbf342 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java @@ -46,20 +46,29 @@ final class DtoMetaBuilder { } static String propertyName(String methodName) { - final String name = methodName.substring(3); - return Character.toLowerCase(name.charAt(0)) + name.substring(1); + if (isTraditionalSetterMethod(methodName)) { + final String name = methodName.substring(3); + return Character.toLowerCase(name.charAt(0)) + name.substring(1); + } else { + // accessor style setter method + return methodName; + } + } + + private static boolean isTraditionalSetterMethod(String methodName) { + return methodName.startsWith("set") && methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3)); } /** * Include a public "setter" method - 1 argument, returns void. */ static boolean includeMethod(Method method) { + String name = method.getName(); final int modifiers = method.getModifiers(); return Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) - && Void.TYPE.equals(method.getReturnType()) && method.getParameterTypes().length == 1 - && method.getName().startsWith("set") && method.getName().length() > 3; + && (!name.equals("wait") && !name.equals("equals")); } private void readConstructors() { diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/dto/DtoMetaBuilderTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/dto/DtoMetaBuilderTest.java index a3cf2a2fd..9448e1a5f 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/dto/DtoMetaBuilderTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/dto/DtoMetaBuilderTest.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.dto; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import java.lang.reflect.Method; @@ -12,42 +11,54 @@ import static org.assertj.core.api.Assertions.assertThat; public class DtoMetaBuilderTest { @Test - public void includeMethod() { + void includeMethod() { Map methods = getIncludedMethodsFor(D0.class); assertThat(methods).hasSize(2); - assertThat(methods.get("setName")).isNotNull(); - assertThat(methods.get("setId")).isNotNull(); + assertThat(methods).containsKeys("setId", "setName"); } @Test - public void includeMethod_when_notStrictlySetters() { + void includeMethod_when_notStrictlySetters() { Map methods = getIncludedMethodsFor(D1.class); - assertThat(methods).hasSize(3); - assertThat(methods.get("setNameThen")).isNotNull(); - assertThat(methods.get("setIdFor")).isNotNull(); - assertThat(methods.get("setI")).isNotNull(); + assertThat(methods).hasSize(5); + assertThat(methods).containsKeys("setNameThen", "setIdFor", "setI", "setA", "set"); } @Test - public void propertyType() { + void includeMethod_when_fluidAccessors() { + Map methods = getIncludedMethodsFor(D2FluidAccessors.class); + + assertThat(methods).hasSize(5); + assertThat(methods).containsKeys("nameThen", "idFor", "a", "i", "set"); + } + + @Test + void includeMethod_when_plainAccessors() { + Map methods = getIncludedMethodsFor(D2PlainAccessors.class); + + assertThat(methods).hasSize(5); + assertThat(methods).containsKeys("nameThen", "idFor", "a", "i", "set"); + } + + @Test + void propertyType() { Map methods = getIncludedMethodsFor(D0.class); assertThat(methods).hasSize(2); - Assertions.assertThat(DtoMetaProperty.propertyClass(methods.get("setName"))).isEqualTo(String.class); + assertThat(DtoMetaProperty.propertyClass(methods.get("setName"))).isEqualTo(String.class); assertThat(DtoMetaProperty.propertyClass(methods.get("setId"))).isEqualTo(long.class); assertThat(DtoMetaProperty.propertyType(methods.get("setName"))).isEqualTo(String.class); assertThat(DtoMetaProperty.propertyType(methods.get("setId"))).isEqualTo(long.class); } @Test - public void propertyName() { - - Assertions.assertThat(DtoMetaBuilder.propertyName("setName")).isEqualTo("name"); + void propertyName() { + assertThat(DtoMetaBuilder.propertyName("setName")).isEqualTo("name"); assertThat(DtoMetaBuilder.propertyName("setId")).isEqualTo("id"); assertThat(DtoMetaBuilder.propertyName("setI")).isEqualTo("i"); - assertThat(DtoMetaBuilder.propertyName("setfoo")).isEqualTo("foo"); + assertThat(DtoMetaBuilder.propertyName("setFoo")).isEqualTo("foo"); } @@ -120,4 +131,47 @@ public class DtoMetaBuilderTest { return this; } } + + @SuppressWarnings("unused") + static class D2FluidAccessors { + + public D2FluidAccessors nameThen(String name) { + return this; + } + + public D2FluidAccessors idFor(long id) { + return this; + } + + public D2FluidAccessors i(long val) { + return this; + } + + public D2FluidAccessors set(long val) { + return this; + } + + public D2FluidAccessors a(long val) { + return this; + } + } + + @SuppressWarnings("unused") + static class D2PlainAccessors { + + public void nameThen(String name) { + } + + public void idFor(long id) { + } + + public void i(long val) { + } + + public void set(long val) { + } + + public void a(long val) { + } + } } diff --git a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java index 8b86e635c..f702d4c14 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java +++ b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java @@ -24,12 +24,36 @@ public class DtoQuery2Test extends BaseTestCase { private static final Logger log = LoggerFactory.getLogger(DtoQuery2Test.class); @Test - public void dto_findList_constructorMatch() { + void dto_findList_fluidAccessors() { + ResetBasicData.reset(); + List list = server().findDto(DCustFluidAccessors.class, "select id, name from o_customer").findList(); + + assertThat(list).isNotEmpty(); + for (DCustFluidAccessors cust: list) { + assertThat(cust.id()).isNotNull(); + assertThat(cust.name()).isNotNull(); + } + } + + @Test + void dto_findList_plainAccessors() { + ResetBasicData.reset(); + + List list = server().findDto(DCustPlainAccessors.class, "select id, name from o_customer").findList(); + + assertThat(list).isNotEmpty(); + for (DCustPlainAccessors cust: list) { + assertThat(cust.id()).isNotNull(); + assertThat(cust.name()).isNotNull(); + } + } + + @Test + void dto_findList_constructorMatch() { ResetBasicData.reset(); DtoQuery dtoQuery = server().findDto(DCust.class, "select id, name from o_customer"); - List list = dtoQuery.findList(); log.info(list.toString()); @@ -37,7 +61,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findIterator_closeWithResources() { + void dto_findIterator_closeWithResources() { ResetBasicData.reset(); int counter = 0; @@ -55,7 +79,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findIterator() { + void dto_findIterator() { ResetBasicData.reset(); final int expectedCount = server().find(Customer.class).findCount(); @@ -80,7 +104,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findStream() { + void dto_findStream() { ResetBasicData.reset(); final int expectedCount = server().find(Customer.class).findCount(); @@ -104,8 +128,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findEach_constructorMatch() { - + void dto_findEach_constructorMatch() { ResetBasicData.reset(); LoggedSql.start(); @@ -118,8 +141,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findEachWhile_constructorMatch() { - + void dto_findEachWhile_constructorMatch() { ResetBasicData.reset(); LoggedSql.start(); @@ -135,8 +157,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findOneEmpty() { - + void dto_findOneEmpty() { ResetBasicData.reset(); Optional rob = server().findDto(DCust.class, "select id, name from o_customer where name = :name") @@ -153,8 +174,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findOne() { - + void dto_findOne() { ResetBasicData.reset(); DCust fiona = server().findDto(DCust.class, "select id, name from o_customer where name = :name") @@ -172,8 +192,7 @@ public class DtoQuery2Test extends BaseTestCase { @Test - public void dto_queryPlanHits() { - + void dto_queryPlanHits() { ResetBasicData.reset(); resetAllMetrics(); @@ -218,8 +237,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findList_relaxedMode() { - + void dto_findList_relaxedMode() { ResetBasicData.reset(); List list = server().findDto(DCust2.class, "select id, '42' as something_we_cannot_map, name from o_customer") @@ -231,8 +249,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findList_relaxedMode_defaultConstructor() { - + void dto_findList_relaxedMode_defaultConstructor() { ResetBasicData.reset(); List list = server().findDto(DCust2.class, "select id, '42' as something_we_cannot_map, name from o_customer") @@ -244,8 +261,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findList_constructorPlusMatch() { - + void dto_findList_constructorPlusMatch() { ResetBasicData.reset(); String sql = "select c.id, c.name, count(o.id) as totalOrders\n" + @@ -263,8 +279,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto_findList_setters() { - + void dto_findList_setters() { ResetBasicData.reset(); DtoQuery dtoQuery = server().findDto(DCust2.class, "select id, name from o_customer"); @@ -275,8 +290,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto3_findList_constructorMatch() { - + void dto3_findList_constructorMatch() { ResetBasicData.reset(); List robs = server().findDto(DCust3.class, "select id, name, 42 as totalOrders from o_customer where name like ?") @@ -290,8 +304,7 @@ public class DtoQuery2Test extends BaseTestCase { } @Test - public void dto3_findList_settersMatch() { - + void dto3_findList_settersMatch() { ResetBasicData.reset(); List robs = server().findDto(DCust3.class, "select id, name from o_customer where name = :name") @@ -305,9 +318,7 @@ public class DtoQuery2Test extends BaseTestCase { public static class DCust { final Integer id; - final String name; - int totalOrders; public DCust(Integer id, String name) { @@ -340,7 +351,6 @@ public class DtoQuery2Test extends BaseTestCase { public static class DCust2 { Integer id; - String name; @Override @@ -368,9 +378,7 @@ public class DtoQuery2Test extends BaseTestCase { public static class DCust3 { Integer id; - String name; - int totalOrders; public DCust3() { @@ -411,4 +419,60 @@ public class DtoQuery2Test extends BaseTestCase { this.name = name; } } + + public static class DCustFluidAccessors { + + Integer id; + String name; + + @Override + public String toString() { + return "id:" + id + " name:" + name; + } + + public Integer id() { + return id; + } + + public DCustFluidAccessors id(Integer id) { + this.id = id; + return this; + } + + public String name() { + return name; + } + + public DCustFluidAccessors name(String name) { + this.name = name; + return this; + } + } + + public static class DCustPlainAccessors { + + Integer id; + String name; + + @Override + public String toString() { + return "id:" + id + " name:" + name; + } + + public Integer id() { + return id; + } + + public void id(Integer id) { + this.id = id; + } + + public String name() { + return name; + } + + public void name(String name) { + this.name = name; + } + } } From 04434215d0931e4d9db2f27bc3b629d383bede1f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 6 Jul 2022 14:27:28 +1200 Subject: [PATCH 09/35] #2740 - Bump ebean-test-containers to 6.2 --- .../io/ebean/test/config/platform/Config.java | 9 +-- .../test/config/platform/DockerHost.java | 55 ------------------- pom.xml | 2 +- 3 files changed, 3 insertions(+), 63 deletions(-) delete mode 100644 ebean-test/src/main/java/io/ebean/test/config/platform/DockerHost.java diff --git a/ebean-test/src/main/java/io/ebean/test/config/platform/Config.java b/ebean-test/src/main/java/io/ebean/test/config/platform/Config.java index 4dd36034a..44207a393 100644 --- a/ebean-test/src/main/java/io/ebean/test/config/platform/Config.java +++ b/ebean-test/src/main/java/io/ebean/test/config/platform/Config.java @@ -2,6 +2,7 @@ package io.ebean.test.config.platform; import io.ebean.config.DatabaseConfig; import io.ebean.datasource.DataSourceConfig; +import io.ebean.test.containers.DockerHost; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +39,6 @@ class Config { private final DatabaseConfig config; private boolean containerDropCreate; private final Properties dockerProperties = new Properties(); - private final DockerHost dockerHost = new DockerHost(); Config(String db, String platform, String databaseName, DatabaseConfig config) { this.db = db; @@ -241,8 +241,7 @@ class Config { } String host() { - String explicitDockerHost = getKey("dockerHost", null); - return getKey("host", dockerHost.dockerHost(explicitDockerHost)); + return getKey("host", getKey("dockerHost", DockerHost.host())); } /** @@ -385,10 +384,6 @@ class Config { } private void initDockerProperties() { - if (dockerHost.runningInDocker()) { - // tell ebean-docker-test we are not using localhost (for jdbc DB setup commands) - dockerProperties.setProperty(dockerKey("host"), dockerHost.dockerHost()); - } dockerProperties.setProperty(dockerKey("port"), String.valueOf(port)); dockerProperties.setProperty(dockerKey("dbName"), databaseName); if (schema != null) { diff --git a/ebean-test/src/main/java/io/ebean/test/config/platform/DockerHost.java b/ebean-test/src/main/java/io/ebean/test/config/platform/DockerHost.java deleted file mode 100644 index 5e3f0ce94..000000000 --- a/ebean-test/src/main/java/io/ebean/test/config/platform/DockerHost.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.ebean.test.config.platform; - -import java.io.File; -import java.util.Locale; - -/** - * Helper to detect if running inside docker and determine host name for that case. - */ -class DockerHost { - - private final boolean runningInDocker; - private String dockerHost; - - DockerHost() { - runningInDocker = initInDocker(); - } - - boolean runningInDocker() { - return runningInDocker; - } - - String dockerHost() { - return dockerHost; - } - - String dockerHost(String explicitHost) { - if (!runningInDocker) { - return "localhost"; - } - dockerHost = explicitHost != null ? explicitHost : defaultDockerHost(); - return dockerHost; - } - - /** - * Return true if running inside a docker container (we are using docker in docker). - */ - boolean initInDocker() { - return new File("/.dockerenv").exists(); - } - - /** - * Return the default host name to use when running in docker. - *

- * Can instead be explicitly specified via ebean.test.dockerHost. - */ - String defaultDockerHost() { - String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); - if (os.contains("mac") || os.contains("darwin") || os.contains("win")) { - return "host.docker.internal"; - } else { - return "172.17.0.1"; - } - } - -} diff --git a/pom.xml b/pom.xml index 4e2418885..381584a8d 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 2.0 1.2 13.6.0 - 6.1 + 6.2 8.0 13.6.5 13.6.5 From 43dac07d5b04107a9965609e3550ada4df7b1fc9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 6 Jul 2022 14:41:24 +1200 Subject: [PATCH 10/35] #2740 - Bump ebean-test-containers to 6.2 --- .../test/config/platform/RedisSetup.java | 8 +- .../test/config/platform/DockerHostTest.java | 87 ------------------- 2 files changed, 3 insertions(+), 92 deletions(-) delete mode 100644 ebean-test/src/test/java/io/ebean/test/config/platform/DockerHostTest.java diff --git a/ebean-test/src/main/java/io/ebean/test/config/platform/RedisSetup.java b/ebean-test/src/main/java/io/ebean/test/config/platform/RedisSetup.java index 0fd933d26..5dc46ade5 100644 --- a/ebean-test/src/main/java/io/ebean/test/config/platform/RedisSetup.java +++ b/ebean-test/src/main/java/io/ebean/test/config/platform/RedisSetup.java @@ -1,5 +1,6 @@ package io.ebean.test.config.platform; +import io.ebean.test.containers.DockerHost; import io.ebean.test.containers.RedisContainer; import java.util.Properties; @@ -10,11 +11,8 @@ class RedisSetup { String version = properties.getProperty("ebean.test.redis"); version = properties.getProperty("ebean.test.redis.version", version); if (version != null) { - DockerHost dockerHost = new DockerHost(); - if (dockerHost.runningInDocker()) { - String host = dockerHost.dockerHost(properties.getProperty("ebean.test.dockerHost")); - properties.setProperty("redis.host", host); - } + String host = properties.getProperty("ebean.test.dockerHost", DockerHost.host()); + properties.setProperty("redis.host", host); RedisContainer.builder(version) .properties(properties) .build() diff --git a/ebean-test/src/test/java/io/ebean/test/config/platform/DockerHostTest.java b/ebean-test/src/test/java/io/ebean/test/config/platform/DockerHostTest.java deleted file mode 100644 index 0be8a5d43..000000000 --- a/ebean-test/src/test/java/io/ebean/test/config/platform/DockerHostTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.ebean.test.config.platform; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class DockerHostTest { - - @Test - void runningInDocker_when_false_alwaysUseLocalhost() { - DockerHost dockerHost = new DockerHost(); - assertFalse(dockerHost.runningInDocker()); - assertEquals("localhost", dockerHost.dockerHost("foo")); - } - - @Test - void runningInDocker_when_true_useExplicit() { - TDDockerHost dockerHost = new TDDockerHost(); - assertTrue(dockerHost.runningInDocker()); - - assertEquals("my-host", dockerHost.dockerHost("my-host")); - } - - @Disabled - @Test - void runningInDocker_when_trueAndLinux_useDefault() { - TDDockerHost dockerHost = new TDDockerHost(); - assertTrue(dockerHost.runningInDocker()); - - assertEquals("172.17.0.1", dockerHost.dockerHost(null)); - } - - @Test - void runningInDocker_when_windowsDefault() { - TDDockerHost dockerHost = new TDDockerHost(); - assertTrue(dockerHost.runningInDocker()); - - String origName = System.getProperty("os.name"); - System.setProperty("os.name", "win"); - try { - assertEquals("host.docker.internal",dockerHost.defaultDockerHost()); - assertEquals("host.docker.internal", dockerHost.dockerHost(null)); - } finally { - System.setProperty("os.name", origName); - } - } - - @Test - void runningInDocker_when_macDefault() { - TDDockerHost dockerHost = new TDDockerHost(); - assertTrue(dockerHost.runningInDocker()); - - String origName = System.getProperty("os.name"); - System.setProperty("os.name", "mac"); - try { - assertEquals("host.docker.internal",dockerHost.defaultDockerHost()); - assertEquals("host.docker.internal", dockerHost.dockerHost(null)); - } finally { - System.setProperty("os.name", origName); - } - } - - - @Test - void runningInDocker_when_linuxDefault() { - TDDockerHost dockerHost = new TDDockerHost(); - assertTrue(dockerHost.runningInDocker()); - - String origName = System.getProperty("os.name"); - System.setProperty("os.name", "linux"); - try { - assertEquals("172.17.0.1",dockerHost.defaultDockerHost()); - assertEquals("172.17.0.1", dockerHost.dockerHost(null)); - } finally { - System.setProperty("os.name", origName); - } - } - - static class TDDockerHost extends DockerHost { - - @Override - boolean initInDocker() { - return true; - } - } -} From 88b6a60feb005effd7a925f351ef0090b05ae1ec Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 6 Jul 2022 20:19:41 +1200 Subject: [PATCH 11/35] #2730 - Secondary @OneToMany fetch query is not happening if the same Entity type is fetched --- .../server/deploy/DbReadContext.java | 6 - .../io/ebeaninternal/server/query/CQuery.java | 8 -- .../server/query/SqlTreeLoadBean.java | 14 +- .../server/query/SqlTreeLoadManyRoot.java | 4 + .../java/org/tests/o2m/recurse/RMItem.java | 51 +++++++ .../org/tests/o2m/recurse/RMItemHolder.java | 80 +++++++++++ .../TestFetchOneToManySameTypeTwoPaths.java | 133 ++++++++++++++++++ 7 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 ebean-test/src/test/java/org/tests/o2m/recurse/RMItem.java create mode 100644 ebean-test/src/test/java/org/tests/o2m/recurse/RMItemHolder.java create mode 100644 ebean-test/src/test/java/org/tests/o2m/recurse/TestFetchOneToManySameTypeTwoPaths.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbReadContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbReadContext.java index 0ed8284d8..e79e7e0df 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbReadContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbReadContext.java @@ -6,7 +6,6 @@ import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.PersistenceContext; import io.ebean.core.type.DataReader; import io.ebeaninternal.api.SpiQuery; -import io.ebeaninternal.server.query.STreePropertyAssocMany; import java.util.Map; @@ -70,11 +69,6 @@ public interface DbReadContext { */ void register(BeanPropertyAssocMany many, BeanCollection bc); - /** - * Return the property that is associated with the many. There can only be - * one. This can be null. - */ - STreePropertyAssocMany getManyProperty(); /** * Set back the bean that has just been loaded with its id. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java index 3566ee08a..d153c359a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java @@ -605,14 +605,6 @@ public final class CQuery implements DbReadContext, CancelableQuery, SpiProfi return logWhereSql; } - /** - * Return the property that is associated with the many. There can only be one - * per SqlSelect. This can be null. - */ - @Override - public STreePropertyAssocMany getManyProperty() { - return manyProperty; - } public String getBindLog() { return bindLog; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java index 664c5e24f..312fb359a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java @@ -36,6 +36,7 @@ class SqlTreeLoadBean implements SqlTreeLoad { private final SpiQuery.TemporalMode temporalMode; private final boolean temporalVersions; final IdBinder lazyLoadParentIdBinder; + private final STreePropertyAssocMany loadingChildProperty; SqlTreeLoadBean(SqlTreeNodeBean node) { this.lazyLoadParent = node.lazyLoadParent; @@ -55,6 +56,16 @@ class SqlTreeLoadBean implements SqlTreeLoad { this.properties = node.properties; this.pathMap = node.pathMap; this.children = node.createLoadChildren(); + this.loadingChildProperty = loadingChildProperty(); + } + + private STreePropertyAssocMany loadingChildProperty() { + for (SqlTreeLoad child : children) { + if (child instanceof SqlTreeLoadManyRoot) { + return ((SqlTreeLoadManyRoot) child).manyProp(); + } + } + return null; } boolean isRoot() { @@ -280,10 +291,9 @@ class SqlTreeLoadBean implements SqlTreeLoad { * included in the actual query. */ private void createListProxies() { - STreePropertyAssocMany fetchedMany = ctx.getManyProperty(); boolean forceNewReference = queryMode == Mode.REFRESH_BEAN; for (STreePropertyAssocMany many : localDesc.propsMany()) { - if (many != fetchedMany) { + if (many != loadingChildProperty) { if (readOnlyNoIntercept) { many.createEmptyReference(localBean); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadManyRoot.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadManyRoot.java index 3622e770e..560a231e9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadManyRoot.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadManyRoot.java @@ -14,6 +14,10 @@ final class SqlTreeLoadManyRoot extends SqlTreeLoadBean { this.manyProp = node.manyProp; } + STreePropertyAssocMany manyProp() { + return manyProp; + } + @Override public EntityBean load(DbReadContext cquery, EntityBean parentBean, EntityBean contextParent) throws SQLException { // pass in null for parentBean because added to a collection rather than set to the parentBean diff --git a/ebean-test/src/test/java/org/tests/o2m/recurse/RMItem.java b/ebean-test/src/test/java/org/tests/o2m/recurse/RMItem.java new file mode 100644 index 000000000..a08a0a58f --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/recurse/RMItem.java @@ -0,0 +1,51 @@ +package org.tests.o2m.recurse; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class RMItem { + + @Id + private long itemId; + + @ManyToOne + @JoinColumn(name = "item_group_id") + private RMItem itemGroup; + + private String name; + + @OneToMany(mappedBy = "itemGroup") + private List subItems; + + public RMItem() { + } + + public RMItem(String name) { + this.name = name; + } + + public Long getItemId() { + return itemId; + } + + public void setItemId(Long itemId) { + this.itemId = itemId; + } + + public RMItem getItemGroup() { + return itemGroup; + } + + public void setItemGroup(RMItem itemGroup) { + this.itemGroup = itemGroup; + } + + public List getSubItems() { + return subItems; + } + + public void setSubItems(List subItems) { + this.subItems = subItems; + } +} diff --git a/ebean-test/src/test/java/org/tests/o2m/recurse/RMItemHolder.java b/ebean-test/src/test/java/org/tests/o2m/recurse/RMItemHolder.java new file mode 100644 index 000000000..aa77c3e73 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/recurse/RMItemHolder.java @@ -0,0 +1,80 @@ +package org.tests.o2m.recurse; + +import io.ebean.Model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Version; + +@Entity +public class RMItemHolder extends Model { + + @Id + long id; + String name; + String notes; + @ManyToOne + //@JoinColumn(name = "item_a_id") + private RMItem itemA; + @ManyToOne + //@JoinColumn(name = "item_b_id") + private RMItem itemB; + @Version + long version; + + public RMItemHolder(String name) { + this.name = name; + } + + public RMItemHolder() { + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public RMItem getItemA() { + return itemA; + } + + public void setItemA(RMItem itemA) { + this.itemA = itemA; + } + + public RMItem getItemB() { + return itemB; + } + + public void setItemB(RMItem itemB) { + this.itemB = itemB; + } +} diff --git a/ebean-test/src/test/java/org/tests/o2m/recurse/TestFetchOneToManySameTypeTwoPaths.java b/ebean-test/src/test/java/org/tests/o2m/recurse/TestFetchOneToManySameTypeTwoPaths.java new file mode 100644 index 000000000..34df0ac88 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/recurse/TestFetchOneToManySameTypeTwoPaths.java @@ -0,0 +1,133 @@ +package org.tests.o2m.recurse; + +import io.ebean.DB; +import io.ebean.Database; +import io.ebean.FetchConfig; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class TestFetchOneToManySameTypeTwoPaths { + + @Test + void testSubItemListFetch_ofQuery() { + Database server = DB.getDefault(); + + RMItem itemA = new RMItem("a"); + server.save(itemA); + RMItem itemB = new RMItem("b"); + server.save(itemB); + + for (int i=0; i<2; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemA); + server.save(subItem); + } + + for (int i=0; i<3; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemB); + server.save(subItem); + } + + RMItemHolder customer = new RMItemHolder(); + customer.setItemA(itemA); + customer.setItemB(itemB); + server.save(customer); + + // This is OK + { + RMItemHolder requestedCustomer = server.find(RMItemHolder.class) + .setDisableLazyLoading(true) + .fetch("itemA.subItems", FetchConfig.ofQuery()) + .fetch("itemB.subItems", FetchConfig.ofQuery()) + .where() + .eq("id", customer.getId()) + .findOne(); + assertEquals(2, requestedCustomer.getItemA().getSubItems().size()); + assertEquals(3, requestedCustomer.getItemB().getSubItems().size()); + } + } + + @Test + void testSubItemListFetch_itemAFirst() { + Database server = DB.getDefault(); + + RMItem itemA = new RMItem("aa"); + server.save(itemA); + RMItem itemB = new RMItem("bb"); + server.save(itemB); + + for (int i=0; i<2; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemA); + server.save(subItem); + } + + for (int i=0; i<3; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemB); + server.save(subItem); + } + + RMItemHolder customer = new RMItemHolder(); + customer.setItemA(itemA); + customer.setItemB(itemB); + server.save(customer); + + // This fails because requestedCustomer.getItemB().getSubItems() is not loaded + { + RMItemHolder requestedCustomer = server.find(RMItemHolder.class) + .setDisableLazyLoading(true) + .fetch("itemA.subItems") + .fetch("itemB.subItems") + .where() + .eq("id", customer.getId()) + .findOne(); + assertEquals(2, requestedCustomer.getItemA().getSubItems().size()); + assertEquals(3, requestedCustomer.getItemB().getSubItems().size()); + } + } + + @Test + void testSubItemListFetch_itemBFirst() { + Database server = DB.getDefault(); + + RMItem itemA = new RMItem("a"); + server.save(itemA); + RMItem itemB = new RMItem("b"); + server.save(itemB); + + for (int i=0; i<2; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemA); + server.save(subItem); + } + + for (int i=0; i<5; i++) { + RMItem subItem = new RMItem(); + subItem.setItemGroup(itemB); + server.save(subItem); + } + + RMItemHolder customer = new RMItemHolder(); + customer.setItemA(itemA); + customer.setItemB(itemB); + server.save(customer); + + // This fails because requestedCustomer.getItemA().getSubItems() is not loaded + { + RMItemHolder requestedCustomer = server.find(RMItemHolder.class) + .setDisableLazyLoading(true) + .fetch("itemB.subItems") + .fetch("itemA.subItems") + .where() + .eq("id", customer.getId()) + .findOne(); + assertEquals(2, requestedCustomer.getItemA().getSubItems().size()); + assertEquals(5, requestedCustomer.getItemB().getSubItems().size()); + System.out.println("here"); + } + } + +} From 11e20edb593e301244348b60ba03fc420bc0f8aa Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 6 Jul 2022 20:47:54 +1200 Subject: [PATCH 12/35] #2741 - Bump avaje-config to 2.1 and modify ebean-test to support use of ${docker.host} in test container jdbc urls --- ebean-api/pom.xml | 2 +- .../io/ebean/test/config/AutoConfigureForTesting.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index fc1ccc676..436d95abc 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -27,7 +27,7 @@ io.avaje avaje-config - 2.0 + 2.1 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - HEAD + ebean-parent-13.6.5 ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided @@ -55,7 +55,7 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index ebdcea3a7..b5290f678 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean bom @@ -71,88 +71,88 @@ io.ebean ebean - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-core-type - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-ddl-generator - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-externalmapping-api - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-externalmapping-xml - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-autotune - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-querybean - 13.6.5-SNAPSHOT + 13.6.5 io.ebean querybean-generator - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean kotlin-querybean-generator - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean ebean-test - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-postgis - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-redis - 13.6.5-SNAPSHOT + 13.6.5 diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index f7da6a256..09fc011e4 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 20a71700a..fc5daa15e 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - HEAD + ebean-parent-13.6.5 @@ -41,19 +41,19 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-core-type - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-externalmapping-api - 13.6.5-SNAPSHOT + 13.6.5 @@ -144,21 +144,21 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-platform-postgres - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-platform-sqlserver - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 5745e1c16..24307d015 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided @@ -58,7 +58,7 @@ io.ebean ebean-platform-all - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index 8c6017673..0a03cf803 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index eab4126c8..4af558e3a 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,12 +4,12 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 scm:git:git@github.com:ebean-orm/ebean.git - HEAD + ebean-parent-13.6.5 ebean external mapping xml @@ -28,7 +28,7 @@ io.ebean ebean-externalmapping-api - 13.6.5-SNAPSHOT + 13.6.5 @@ -61,21 +61,21 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-ddl-generator - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index e6a5d7ca8..cd2928aba 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean postgis @@ -22,14 +22,14 @@ io.ebean ebean-platform-postgres - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided @@ -73,7 +73,7 @@ io.ebean ebean-test - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index 518e0d881..375efd0f5 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided @@ -63,21 +63,21 @@ io.ebean ebean-ddl-generator - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean querybean-generator - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-test - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index 37d2f6cb5..f9275f8df 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean ebean-querybean - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean querybean-generator - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-test - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 8e25eeff3..9f6f90bf0 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean test @@ -29,20 +29,20 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 provided io.ebean ebean-ddl-generator - 13.6.5-SNAPSHOT + 13.6.5 @@ -106,7 +106,7 @@ io.ebean ebean-platform-all - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index c36475b2e..6c302f353 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5-SNAPSHOT + 13.6.5 kotlin querybean generator @@ -29,7 +29,7 @@ io.ebean ebean-querybean - 13.6.5-SNAPSHOT + 13.6.5 test @@ -43,7 +43,7 @@ io.ebean ebean-core - 13.6.5-SNAPSHOT + 13.6.5 test @@ -64,14 +64,14 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 test io.ebean ebean-ddl-generator - 13.6.5-SNAPSHOT + 13.6.5 test diff --git a/platforms/all/pom.xml b/platforms/all/pom.xml index 96858a7b2..f2cedcacc 100644 --- a/platforms/all/pom.xml +++ b/platforms/all/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-platform-all @@ -14,68 +14,72 @@ io.ebean ebean-platform-h2 - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-clickhouse - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-db2 - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-hana - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-hsqldb - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-mysql - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-mariadb - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-nuodb - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-oracle - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-postgres - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-sqlanywhere - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-sqlite - 13.6.5-SNAPSHOT + 13.6.5 io.ebean ebean-platform-sqlserver - 13.6.5-SNAPSHOT + 13.6.5 + + + ebean-parent-13.6.5 + diff --git a/platforms/clickhouse/pom.xml b/platforms/clickhouse/pom.xml index b0e35711e..377ff4227 100644 --- a/platforms/clickhouse/pom.xml +++ b/platforms/clickhouse/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-platform-clickhouse @@ -14,8 +14,12 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 + + + ebean-parent-13.6.5 + diff --git a/platforms/db2/pom.xml b/platforms/db2/pom.xml index 3be2c4055..354b6b8b3 100644 --- a/platforms/db2/pom.xml +++ b/platforms/db2/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-platform-db2 @@ -14,8 +14,12 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 + + + ebean-parent-13.6.5 + diff --git a/platforms/h2/pom.xml b/platforms/h2/pom.xml index fe9b57fd2..7abe34530 100644 --- a/platforms/h2/pom.xml +++ b/platforms/h2/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5-SNAPSHOT + 13.6.5 ebean-platform-h2 @@ -14,7 +14,7 @@ io.ebean ebean-api - 13.6.5-SNAPSHOT + 13.6.5 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-13.6.5 + HEAD ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided @@ -55,7 +55,7 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index b5290f678..76fedb28c 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean bom @@ -71,88 +71,88 @@ io.ebean ebean - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-core-type - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-ddl-generator - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-externalmapping-api - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-externalmapping-xml - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-autotune - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-querybean - 13.6.5 + 13.6.6-SNAPSHOT io.ebean querybean-generator - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean kotlin-querybean-generator - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean ebean-test - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-postgis - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-redis - 13.6.5 + 13.6.6-SNAPSHOT diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index 09fc011e4..1d2a7549d 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index fc5daa15e..ac95111d5 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-13.6.5 + HEAD @@ -41,19 +41,19 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-core-type - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-externalmapping-api - 13.6.5 + 13.6.6-SNAPSHOT @@ -144,21 +144,21 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-platform-postgres - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-platform-sqlserver - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 24307d015..f3c3dee3d 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided @@ -58,7 +58,7 @@ io.ebean ebean-platform-all - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index 0a03cf803..bc053d284 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 4af558e3a..d9d749165 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,12 +4,12 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-13.6.5 + HEAD ebean external mapping xml @@ -28,7 +28,7 @@ io.ebean ebean-externalmapping-api - 13.6.5 + 13.6.6-SNAPSHOT @@ -61,21 +61,21 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-ddl-generator - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index cd2928aba..ca7ade150 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean postgis @@ -22,14 +22,14 @@ io.ebean ebean-platform-postgres - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided @@ -73,7 +73,7 @@ io.ebean ebean-test - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index 375efd0f5..9d5b91b01 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided @@ -63,21 +63,21 @@ io.ebean ebean-ddl-generator - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean querybean-generator - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-test - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index f9275f8df..122d21d26 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean ebean-querybean - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean querybean-generator - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-test - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 9f6f90bf0..fc97ae264 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean test @@ -29,20 +29,20 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT provided io.ebean ebean-ddl-generator - 13.6.5 + 13.6.6-SNAPSHOT @@ -106,7 +106,7 @@ io.ebean ebean-platform-all - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 6c302f353..68283606f 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 13.6.5 + 13.6.6-SNAPSHOT kotlin querybean generator @@ -29,7 +29,7 @@ io.ebean ebean-querybean - 13.6.5 + 13.6.6-SNAPSHOT test @@ -43,7 +43,7 @@ io.ebean ebean-core - 13.6.5 + 13.6.6-SNAPSHOT test @@ -64,14 +64,14 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT test io.ebean ebean-ddl-generator - 13.6.5 + 13.6.6-SNAPSHOT test diff --git a/platforms/all/pom.xml b/platforms/all/pom.xml index f2cedcacc..a2fa481f0 100644 --- a/platforms/all/pom.xml +++ b/platforms/all/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-platform-all @@ -14,72 +14,68 @@ io.ebean ebean-platform-h2 - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-clickhouse - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-db2 - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-hana - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-hsqldb - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-mysql - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-mariadb - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-nuodb - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-oracle - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-postgres - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-sqlanywhere - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-sqlite - 13.6.5 + 13.6.6-SNAPSHOT io.ebean ebean-platform-sqlserver - 13.6.5 + 13.6.6-SNAPSHOT - - - ebean-parent-13.6.5 - diff --git a/platforms/clickhouse/pom.xml b/platforms/clickhouse/pom.xml index 377ff4227..93c24571b 100644 --- a/platforms/clickhouse/pom.xml +++ b/platforms/clickhouse/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-platform-clickhouse @@ -14,12 +14,8 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT - - - ebean-parent-13.6.5 - diff --git a/platforms/db2/pom.xml b/platforms/db2/pom.xml index 354b6b8b3..4068ecf8a 100644 --- a/platforms/db2/pom.xml +++ b/platforms/db2/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-platform-db2 @@ -14,12 +14,8 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT - - - ebean-parent-13.6.5 - diff --git a/platforms/h2/pom.xml b/platforms/h2/pom.xml index 7abe34530..b7c653968 100644 --- a/platforms/h2/pom.xml +++ b/platforms/h2/pom.xml @@ -4,7 +4,7 @@ platforms io.ebean - 13.6.5 + 13.6.6-SNAPSHOT ebean-platform-h2 @@ -14,7 +14,7 @@ io.ebean ebean-api - 13.6.5 + 13.6.6-SNAPSHOT + + io.avaje + avaje-applog-slf4j + 1.0 + test + + io.ebean ebean-platform-all diff --git a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java index f702d4c14..5c62ac653 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java +++ b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java @@ -210,7 +210,7 @@ public class DtoQuery2Test extends BaseTestCase { } // collect without reset - BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true); + BasicMetricVisitor basic = new BasicMetricVisitor("db", false, true, true, true); server().metaInfo().visitMetrics(basic); List stats = basic.queryMetrics(); diff --git a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java index 4717fabf4..a97dbc39a 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java +++ b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java @@ -298,7 +298,7 @@ public class DtoQueryTest extends BaseTestCase { } // collect without reset - BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true); + BasicMetricVisitor basic = new BasicMetricVisitor("db", false, true, true, true); server().metaInfo().visitMetrics(basic); List stats = basic.queryMetrics(); @@ -322,6 +322,8 @@ public class DtoQueryTest extends BaseTestCase { log.info("stats " + stats); + String asJson = server().metaInfo().metricsAsJson(metric2).withHash(false).withNewLine(false).json(); + assertThat(asJson).contains("dto.DCust_basic2"); } @Test From 648bdf4553f5c1ad8f220cd9be44f165ecbb7d25 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Jul 2022 15:07:17 +1200 Subject: [PATCH 31/35] Bump ebean-dll-runner to 2.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc864c1a2..c31cf8e8f 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ false 2.13.2 2.1.212 - 2.0 + 2.2 1.2 13.6.0 6.2 From 31ac0f794f28966098ce5fa9166df23ae7a7faba Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Jul 2022 21:12:19 +1200 Subject: [PATCH 32/35] Add avaje-applog-slf4j dependency to ebean-api This means by default AppLog logging goes to slf4j-api. Exclude this dependency to otherwise control the AppLog System.Logger implementation. --- ebean-api/pom.xml | 6 ++++++ ebean-test/pom.xml | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 9f49c5027..097d918c6 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -30,6 +30,12 @@ 2.2 + + io.avaje + avaje-applog-slf4j + 1.0 + + - - io.avaje - avaje-applog-slf4j - 1.0 - test - - io.ebean ebean-platform-all From 0100d024d91050cfd8f081c1a770d06ded3f58c2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Jul 2022 22:25:10 +1200 Subject: [PATCH 33/35] #2750 #2751 SoftDeleted entity included via lazy loading (Jackson serialisation) The effective fix is in DLoadContext, only allow includeSoftDeletes to be set from the query when the query is SpiQuery.Mode.NORMAL (not a lazy loading query). --- .../java/io/ebeaninternal/server/core/DefaultBeanLoader.java | 2 +- .../java/io/ebeaninternal/server/loadcontext/DLoadContext.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java index 854842b21..5bdf93a34 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java @@ -199,7 +199,7 @@ final class DefaultBeanLoader { query.setLazyLoadProperty(ebi.getLazyLoadProperty()); if (draft) { query.asDraft(); - } else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN) { + } else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) { query.setIncludeSoftDeletes(); } if (embeddedOwnerIndex > -1) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java index bfef45804..36cb0ee15 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java @@ -101,7 +101,7 @@ public final class DLoadContext implements LoadContext { this.useDocStore = query.isUseDocStore(); this.asOf = query.getAsOf(); this.asDraft = query.isAsDraft(); - this.includeSoftDeletes = query.isIncludeSoftDeletes(); + this.includeSoftDeletes = query.isIncludeSoftDeletes() && query.getMode() == SpiQuery.Mode.NORMAL; this.readOnly = query.isReadOnly(); this.disableReadAudit = query.isDisableReadAudit(); this.disableLazyLoading = query.isDisableLazyLoading(); From 31c20ca9a24e34fe57df0daad595bc6b9b1b503a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Jul 2022 22:26:26 +1200 Subject: [PATCH 34/35] Format and imports on test code only --- .../java/org/tests/o2m/dm/GoodsEntity.java | 36 +++++++++---------- .../java/org/tests/o2m/dm/HistoryColumns.java | 11 +++--- .../java/org/tests/o2m/dm/WorkflowEntity.java | 9 +++-- .../tests/o2m/dm/WorkflowOperationEntity.java | 7 ++-- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java index 7d088f04a..ab29d5435 100644 --- a/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java +++ b/ebean-test/src/test/java/org/tests/o2m/dm/GoodsEntity.java @@ -1,29 +1,29 @@ package org.tests.o2m.dm; -import org.tests.model.draftable.BaseDomain; - -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToOne; @Entity public class GoodsEntity extends HistoryColumns { - private String name; + private String name; - @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) - private WorkflowEntity workflowEntity; + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + private WorkflowEntity workflowEntity; - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public WorkflowEntity getWorkflowEntity() { - return workflowEntity; - } + public WorkflowEntity getWorkflowEntity() { + return workflowEntity; + } - public void setWorkflowEntity(WorkflowEntity workflowEntity) { - this.workflowEntity = workflowEntity; - } + public void setWorkflowEntity(WorkflowEntity workflowEntity) { + this.workflowEntity = workflowEntity; + } } diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/HistoryColumns.java b/ebean-test/src/test/java/org/tests/o2m/dm/HistoryColumns.java index 978475275..31d8f127e 100644 --- a/ebean-test/src/test/java/org/tests/o2m/dm/HistoryColumns.java +++ b/ebean-test/src/test/java/org/tests/o2m/dm/HistoryColumns.java @@ -1,14 +1,11 @@ package org.tests.o2m.dm; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.ebean.annotation.WhenCreated; -import io.ebean.annotation.WhenModified; -import io.ebean.annotation.WhoCreated; -import io.ebean.annotation.WhoModified; import org.tests.model.draftable.BaseDomain; -import javax.persistence.*; -import java.time.LocalDateTime; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; @MappedSuperclass public class HistoryColumns extends BaseDomain { diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java index 44a434a40..1cb1bfa1a 100644 --- a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java +++ b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowEntity.java @@ -1,12 +1,11 @@ package org.tests.o2m.dm; -import com.fasterxml.jackson.annotation.JsonProperty; import io.ebean.annotation.SoftDelete; -import io.ebean.annotation.Where; -import io.ebean.annotation.WhoCreated; -import org.tests.model.draftable.BaseDomain; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; import java.util.ArrayList; import java.util.List; diff --git a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java index e8d862017..325d0b811 100644 --- a/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java +++ b/ebean-test/src/test/java/org/tests/o2m/dm/WorkflowOperationEntity.java @@ -2,11 +2,10 @@ package org.tests.o2m.dm; import com.fasterxml.jackson.annotation.JsonIgnore; import io.ebean.annotation.SoftDelete; -import org.tests.model.draftable.BaseDomain; -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; @Entity public class WorkflowOperationEntity extends HistoryColumns { From 3c2b5f253f1b0dc3add7154eedd1775942540bea Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Jul 2022 22:28:15 +1200 Subject: [PATCH 35/35] Tidy DLoadContext only --- .../ebeaninternal/server/loadcontext/DLoadContext.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java index 36cb0ee15..6b7f47781 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java @@ -234,7 +234,7 @@ public final class DLoadContext implements LoadContext { } } - protected SpiEbeanServer getEbeanServer() { + SpiEbeanServer getEbeanServer() { return ebeanServer; } @@ -242,7 +242,7 @@ public final class DLoadContext implements LoadContext { * Return the parent state which defines the sharedInstance and readOnly status * which needs to be propagated to other beans and collections. */ - protected Boolean isReadOnly() { + Boolean isReadOnly() { return readOnly; } @@ -283,7 +283,7 @@ public final class DLoadContext implements LoadContext { DLoadBeanContext getBeanContextWithInherit(String path, BeanPropertyAssocOne property) { String key = path + ":" + property.targetDescriptor().name(); - return beanMap.computeIfAbsent(key, p -> createBeanContext(property, path, null)); + return beanMap.computeIfAbsent(key, p -> createBeanContext(property, path)); } private void registerSecondaryNode(boolean many, OrmQueryProperties props) { @@ -313,8 +313,8 @@ public final class DLoadContext implements LoadContext { return new DLoadBeanContext(this, p.targetDescriptor(), path, queryProps); } - private DLoadBeanContext createBeanContext(BeanPropertyAssoc property, String path, OrmQueryProperties queryProps) { - return new DLoadBeanContext(this, property.targetDescriptor(), path, queryProps); + private DLoadBeanContext createBeanContext(BeanPropertyAssoc property, String path) { + return new DLoadBeanContext(this, property.targetDescriptor(), path, null); } private BeanProperty getBeanProperty(BeanDescriptor desc, String path) {