From 62712c976f9bcf41b5071f02f7880834150124ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler?= Date: Thu, 26 Aug 2021 14:37:51 +0200 Subject: [PATCH 1/4] ADD: BeanFindController supports postProcessing of retrieved entities --- .../io/ebean/event/BeanFindController.java | 13 +++ .../server/query/DefaultOrmQueryEngine.java | 8 ++ .../ebean/event/BeanFindControllerTest.java | 92 ++++++++++++++++++ .../model/controller/FindControllerMain.java | 54 +++++++++++ .../org/tests/model/controller/SoftRefA.java | 32 +++++++ .../org/tests/model/controller/SoftRefB.java | 32 +++++++ .../controller/TestBeanFindController.java | 94 +++++++++++++++++++ 7 files changed, 325 insertions(+) create mode 100644 ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java create mode 100644 ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java create mode 100644 ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java create mode 100644 ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java diff --git a/ebean-api/src/main/java/io/ebean/event/BeanFindController.java b/ebean-api/src/main/java/io/ebean/event/BeanFindController.java index c81a89e60..4c2799c6c 100644 --- a/ebean-api/src/main/java/io/ebean/event/BeanFindController.java +++ b/ebean-api/src/main/java/io/ebean/event/BeanFindController.java @@ -50,4 +50,17 @@ public interface BeanFindController { */ BeanCollection findMany(BeanQueryRequest request); + /** + * Allows post processing of the find result. + */ + default BeanCollection postProcessMany(BeanQueryRequest request, BeanCollection result) { + return result; + } + + /** + * Allows post processing of the find result. + */ + default T postProcess(BeanQueryRequest request, T result) { + return result; + }; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java index abab7cdf9..29817915c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java @@ -131,6 +131,10 @@ public final class DefaultOrmQueryEngine implements OrmQueryEngine { result = queryEngine.findMany(request); } + if (finder != null) { + result = finder.postProcessMany(request, result); + } + SpiQuery query = request.getQuery(); if (request.isBeanCachePutMany()) { @@ -171,6 +175,10 @@ public final class DefaultOrmQueryEngine implements OrmQueryEngine { result = queryEngine.find(request); } + if (finder != null) { + result = finder.postProcess(request, result); + } + if (result != null && request.isBeanCachePut()) { request.getBeanDescriptor().cacheBeanPut((EntityBean) result); } diff --git a/ebean-core/src/test/java/io/ebean/event/BeanFindControllerTest.java b/ebean-core/src/test/java/io/ebean/event/BeanFindControllerTest.java index 6b2468478..284c4a4ed 100644 --- a/ebean-core/src/test/java/io/ebean/event/BeanFindControllerTest.java +++ b/ebean-core/src/test/java/io/ebean/event/BeanFindControllerTest.java @@ -10,9 +10,14 @@ import org.junit.Test; import org.tests.example.ModUuidGenerator; import org.tests.model.basic.EBasic; import org.tests.model.basic.ECustomId; +import org.tests.model.controller.FindControllerMain; +import org.tests.model.controller.SoftRefA; +import org.tests.model.controller.SoftRefB; +import org.tests.model.controller.TestBeanFindController; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -119,4 +124,91 @@ public class BeanFindControllerTest extends BaseTestCase { b.setName("47"); return b; } + + @Test + public void testPostProcess() { + + Database db = prepareSoftRefs(); + + final FindControllerMain controllerDbA = db.find(FindControllerMain.class, 1); + assertThat(controllerDbA).isNotNull(); + assertThat(controllerDbA.getTarget()) + .isNotNull() + .isInstanceOf(SoftRefA.class) + .hasFieldOrPropertyWithValue("title", "softRefA"); + + final FindControllerMain controllerDbB = db.find(FindControllerMain.class, 2); + assertThat(controllerDbB).isNotNull(); + assertThat(controllerDbB.getTarget()) + .isNotNull() + .isInstanceOf(SoftRefB.class) + .hasFieldOrPropertyWithValue("title", "softRefB"); + + } + + @Test + public void testPostProcessFindMany() { + Database db = prepareSoftRefs(); + + final List controllers = db.find(FindControllerMain.class).orderById(true).findList(); + + assertThat(controllers).hasSize(2); + + final FindControllerMain controllerDbA = controllers.get(0); + assertThat(controllerDbA.getId()).isEqualTo(1); + assertThat(controllerDbA.getTarget()) + .isNotNull() + .isInstanceOf(SoftRefA.class) + .hasFieldOrPropertyWithValue("title", "softRefA"); + + final FindControllerMain controllerDbB = controllers.get(1); + assertThat(controllerDbB.getId()).isEqualTo(2); + assertThat(controllerDbB.getTarget()) + .isNotNull() + .isInstanceOf(SoftRefB.class) + .hasFieldOrPropertyWithValue("title", "softRefB"); + + } + + private Database prepareSoftRefs() { + DatabaseConfig config = new DatabaseConfig(); + + config.setName("h2otherfind"); + config.loadFromProperties(); + config.setDdlGenerate(true); + config.setDdlRun(true); + config.setDdlExtra(false); + + config.setRegister(false); + config.setDefaultServer(false); + config.add(new ModUuidGenerator()); + config.getClasses().add(FindControllerMain.class); + config.getClasses().add(SoftRefA.class); + config.getClasses().add(SoftRefB.class); + + config.getFindControllers().add(new TestBeanFindController()); + + Database db = DatabaseFactory.create(config); + + final SoftRefA softRefA = new SoftRefA(); + softRefA.setTitle("softRefA"); + db.save(softRefA); + + final SoftRefB softRefB = new SoftRefB(); + softRefB.setTitle("softRefB"); + db.save(softRefB); + + final FindControllerMain main1 = new FindControllerMain(); + main1.setTargetId(softRefA.getId()); + main1.setTargetTableName("soft_ref_a"); + db.save(main1); + + final FindControllerMain main2 = new FindControllerMain(); + main2.setTargetId(softRefB.getId()); + main2.setTargetTableName("soft_ref_b"); + db.save(main2); + + return db; + } + } diff --git a/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java b/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java new file mode 100644 index 000000000..524425c6b --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java @@ -0,0 +1,54 @@ +package org.tests.model.controller; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Transient; + +/** + * @author Jonas Pöhler, FOCONIS AG + */ +@Entity +public class FindControllerMain { + + @Id + private Integer id; + + private Integer targetId; + + private String targetTableName; + + @Transient + private Object target; + + public Integer getId() { + return id; + } + + public void setId(final Integer id) { + this.id = id; + } + + public Integer getTargetId() { + return targetId; + } + + public void setTargetId(final Integer targetId) { + this.targetId = targetId; + } + + public String getTargetTableName() { + return targetTableName; + } + + public void setTargetTableName(final String targetTableName) { + this.targetTableName = targetTableName; + } + + public Object getTarget() { + return target; + } + + public void setTarget(final Object target) { + this.target = target; + } +} diff --git a/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java b/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java new file mode 100644 index 000000000..f8d87d7a0 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java @@ -0,0 +1,32 @@ +package org.tests.model.controller; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Jonas Pöhler, FOCONIS AG + */ +@Entity +public class SoftRefA { + + @Id + private Integer id; + + private String title; + + public Integer getId() { + return id; + } + + public void setId(final Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(final String title) { + this.title = title; + } +} diff --git a/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java b/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java new file mode 100644 index 000000000..d2619d4dc --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java @@ -0,0 +1,32 @@ +package org.tests.model.controller; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Jonas Pöhler, FOCONIS AG + */ +@Entity +public class SoftRefB { + + @Id + private Integer id; + + private String title; + + public Integer getId() { + return id; + } + + public void setId(final Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(final String title) { + this.title = title; + } +} diff --git a/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java b/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java new file mode 100644 index 000000000..dde9dab9f --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java @@ -0,0 +1,94 @@ +package org.tests.model.controller; + +import io.ebean.DB; +import io.ebean.bean.BeanCollection; +import io.ebean.bean.EntityBean; +import io.ebean.event.BeanFindController; +import io.ebean.event.BeanQueryRequest; +import io.ebean.plugin.BeanType; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Jonas Pöhler, FOCONIS AG + */ +public class TestBeanFindController implements BeanFindController { + + @Override + public boolean isRegisterFor(final Class cls) { + return cls.isAssignableFrom(FindControllerMain.class); + } + + @Override + public boolean isInterceptFind(final BeanQueryRequest request) { + return false; + } + + @Override + public T find(final BeanQueryRequest request) { + return null; + } + + @Override + public boolean isInterceptFindMany(final BeanQueryRequest request) { + return false; + } + + @Override + public BeanCollection findMany(final BeanQueryRequest request) { + return null; + } + + @Override + public BeanCollection postProcessMany(final BeanQueryRequest request, final BeanCollection result) { + Map, List> elementsMap = new HashMap<>(); + Map, Map> controllerLookup = new HashMap<>(); + + for (Object entry : result.getActualEntries()) { + FindControllerMain findControllerMain = (FindControllerMain) entry; + Class beanType = beanTypeFor(findControllerMain.getTargetTableName(), request); + + if (beanType != null) { + elementsMap.computeIfAbsent(beanType, key -> new ArrayList<>()).add(findControllerMain.getTargetId()); + controllerLookup.computeIfAbsent(beanType, key -> new HashMap<>()).put(findControllerMain.getTargetId(), findControllerMain); + } + } + + elementsMap.forEach((beanType, ids) -> { + final Map idLookup = controllerLookup.get(beanType); + request.getEbeanServer().find(beanType).where() + .idIn(ids).setMapKey("id") + .findMap().forEach((id, bean) -> idLookup.get((Integer) id).setTarget(bean)); + }); + + return result; + } + + @Override + public T postProcess(final BeanQueryRequest request, final T result) { + FindControllerMain findControllerMain = (FindControllerMain) result; + + Class beanType = beanTypeFor(findControllerMain.getTargetTableName(), request); + + if (beanType != null) { + findControllerMain.setTarget(request.getEbeanServer().find(beanType, findControllerMain.getTargetId())); + } + + return result; + } + + private Class beanTypeFor(String tableName, BeanQueryRequest request) { + List> types = request.getEbeanServer() + .getPluginApi().getBeanTypes(tableName); + for (BeanType type : types) { + if (type.isInheritanceRoot()) { + return type.getBeanType(); + } + } + return null; + } + +} From 0cfae9a13b1460e48dbbf7e91941a956548cd8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler?= Date: Mon, 13 Sep 2021 13:15:14 +0200 Subject: [PATCH 2/4] Smaller changes pre-merge --- .../src/main/java/io/ebean/event/BeanFindController.java | 4 ++-- .../java/org/tests/model/controller/FindControllerMain.java | 3 --- .../src/test/java/org/tests/model/controller/SoftRefA.java | 3 --- .../src/test/java/org/tests/model/controller/SoftRefB.java | 3 --- .../org/tests/model/controller/TestBeanFindController.java | 5 ----- 5 files changed, 2 insertions(+), 16 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/event/BeanFindController.java b/ebean-api/src/main/java/io/ebean/event/BeanFindController.java index 4c2799c6c..5190dd063 100644 --- a/ebean-api/src/main/java/io/ebean/event/BeanFindController.java +++ b/ebean-api/src/main/java/io/ebean/event/BeanFindController.java @@ -51,14 +51,14 @@ public interface BeanFindController { BeanCollection findMany(BeanQueryRequest request); /** - * Allows post processing of the find result. + * Allows post-processing of the find result. */ default BeanCollection postProcessMany(BeanQueryRequest request, BeanCollection result) { return result; } /** - * Allows post processing of the find result. + * Allows post-processing of the find result. */ default T postProcess(BeanQueryRequest request, T result) { return result; diff --git a/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java b/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java index 524425c6b..bcc21445f 100644 --- a/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java +++ b/ebean-core/src/test/java/org/tests/model/controller/FindControllerMain.java @@ -4,9 +4,6 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Transient; -/** - * @author Jonas Pöhler, FOCONIS AG - */ @Entity public class FindControllerMain { diff --git a/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java b/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java index f8d87d7a0..41a2bd10e 100644 --- a/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java +++ b/ebean-core/src/test/java/org/tests/model/controller/SoftRefA.java @@ -3,9 +3,6 @@ package org.tests.model.controller; import javax.persistence.Entity; import javax.persistence.Id; -/** - * @author Jonas Pöhler, FOCONIS AG - */ @Entity public class SoftRefA { diff --git a/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java b/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java index d2619d4dc..c7086096e 100644 --- a/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java +++ b/ebean-core/src/test/java/org/tests/model/controller/SoftRefB.java @@ -3,9 +3,6 @@ package org.tests.model.controller; import javax.persistence.Entity; import javax.persistence.Id; -/** - * @author Jonas Pöhler, FOCONIS AG - */ @Entity public class SoftRefB { diff --git a/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java b/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java index dde9dab9f..27cbae2a2 100644 --- a/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java +++ b/ebean-core/src/test/java/org/tests/model/controller/TestBeanFindController.java @@ -1,8 +1,6 @@ package org.tests.model.controller; -import io.ebean.DB; import io.ebean.bean.BeanCollection; -import io.ebean.bean.EntityBean; import io.ebean.event.BeanFindController; import io.ebean.event.BeanQueryRequest; import io.ebean.plugin.BeanType; @@ -12,9 +10,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * @author Jonas Pöhler, FOCONIS AG - */ public class TestBeanFindController implements BeanFindController { @Override From 1fecbbb618a1d5c4612df68d2caf3649d710b938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler?= Date: Mon, 13 Sep 2021 13:33:20 +0200 Subject: [PATCH 3/4] Changes post-merge --- ebean-core/pom.xml | 2 +- ebean-ddl-generator/pom.xml | 2 +- .../test/java/io/ebean/event/BeanFindControllerTest.java | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index b4ae7fb11..6891b082b 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -23,7 +23,7 @@ io.ebean ebean-ddl-runner - 1.1 + 1.0 diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 4fabbbe9b..3a1ef6505 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -17,7 +17,7 @@ io.ebean ebean-ddl-runner - 1.1 + 1.0 diff --git a/ebean-test/src/test/java/io/ebean/event/BeanFindControllerTest.java b/ebean-test/src/test/java/io/ebean/event/BeanFindControllerTest.java index 4deff202b..94be03769 100644 --- a/ebean-test/src/test/java/io/ebean/event/BeanFindControllerTest.java +++ b/ebean-test/src/test/java/io/ebean/event/BeanFindControllerTest.java @@ -10,11 +10,18 @@ import org.junit.jupiter.api.Test; import org.tests.example.ModUuidGenerator; import org.tests.model.basic.EBasic; import org.tests.model.basic.ECustomId; +import org.tests.model.controller.FindControllerMain; +import org.tests.model.controller.SoftRefA; +import org.tests.model.controller.SoftRefB; +import org.tests.model.controller.TestBeanFindController; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class BeanFindControllerTest extends BaseTestCase { From a4eeda6449eb868087315485ff335da51b3944db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler?= Date: Mon, 13 Sep 2021 13:34:14 +0200 Subject: [PATCH 4/4] Revert changes --- ebean-core/pom.xml | 2 +- ebean-ddl-generator/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 6891b082b..b4ae7fb11 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -23,7 +23,7 @@ io.ebean ebean-ddl-runner - 1.0 + 1.1 diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 3a1ef6505..4fabbbe9b 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -17,7 +17,7 @@ io.ebean ebean-ddl-runner - 1.0 + 1.1