This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push: new 21cda93 CAY-2693 Abstract subentities do not have rows materialized correctly 21cda93 is described below commit 21cda9370698e7223263c9269b5ce63f15bb3ffb Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Thu Mar 11 15:00:23 2021 +0300 CAY-2693 Abstract subentities do not have rows materialized correctly --- RELEASE-NOTES.txt | 1 + .../apache/cayenne/map/EntityInheritanceTree.java | 22 ++++---- .../cayenne/map/EntityInheritanceTreeTest.java | 62 +++++++++++++++++++++- 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 8445176..e242a4b 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -29,6 +29,7 @@ CAY-2686 SQL translator incorrectly quotes fully qualified tables' names CAY-2687 Modeler Migrate Repeatedly Asks to Set Column Type for MySQL CAY-2690 dbimport skips length changes for BINARY and VARBINARY columns CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x +CAY-2693 Abstract subentities do not have rows materialized correctly CAY-2694 Precision issues with reverse / forward engineering of time types on MySQL CAY-2695 Reverse engineering on SQLite fails due to feature not being supported CAY-2698 EventSubject.getSubject() is not thread safe diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java b/cayenne-server/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java index 18f859b..0e7df3d 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java @@ -34,7 +34,8 @@ import java.util.Collections; */ public class EntityInheritanceTree { - protected ObjEntity entity; + protected final ObjEntity entity; + protected EntityInheritanceTree parent; protected Collection<EntityInheritanceTree> subentities; protected Expression normalizedQualifier; @@ -43,13 +44,12 @@ public class EntityInheritanceTree { } /** - * Returns a qualifier Expression that matches root entity of this tree and all its - * subentities. + * Returns a qualifier Expression that matches root entity of this tree and all its subentities. */ public Expression qualifierForEntityAndSubclasses() { Expression qualifier = entity.getDeclaredQualifier(); - if (qualifier == null) { + if (qualifier == null && parent == null) { // match all return null; } @@ -58,13 +58,16 @@ public class EntityInheritanceTree { for (EntityInheritanceTree child : subentities) { Expression childQualifier = child.qualifierForEntityAndSubclasses(); - // if any child qualifier is null, just return null, since no filtering is - // possible + // if any child qualifier is null, just return null, since no filtering is possible if (childQualifier == null) { return null; } - qualifier = qualifier.orExp(childQualifier); + if(qualifier == null) { + qualifier = childQualifier; + } else { + qualifier = qualifier.orExp(childQualifier); + } } } @@ -93,7 +96,7 @@ public class EntityInheritanceTree { } // no qualifier ... matches all rows - return entity; + return parent == null ? entity : null; } /** @@ -120,6 +123,7 @@ public class EntityInheritanceTree { } subentities.add(node); + node.parent = this; } public int getChildrenCount() { @@ -127,7 +131,7 @@ public class EntityInheritanceTree { } public Collection<EntityInheritanceTree> getChildren() { - return (subentities != null) ? subentities : Collections.<EntityInheritanceTree>emptyList(); + return (subentities != null) ? subentities : Collections.emptyList(); } public ObjEntity getEntity() { diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/EntityInheritanceTreeTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/EntityInheritanceTreeTest.java index 680d5ab..b18f4fa 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/map/EntityInheritanceTreeTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/map/EntityInheritanceTreeTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.util.Collections; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -76,8 +77,7 @@ public class EntityInheritanceTreeTest { subEntity.setDeclaredQualifier(ExpressionFactory.matchDbExp("x", 1)); dataMap.addObjEntity(subEntity); - // creating EntityInheritanceTree via EntityResolver to ensure the entities are - // indexed + // creating EntityInheritanceTree via EntityResolver to ensure the entities are indexed EntityResolver resolver = new EntityResolver(Collections.singleton(dataMap)); EntityInheritanceTree t1 = resolver.getInheritanceTree("E1"); @@ -94,4 +94,62 @@ public class EntityInheritanceTreeTest { assertSame(entity, t1.entityMatchingRow(row12)); assertNull(t1.entityMatchingRow(row13)); } + + @Test + public void testEntityMatchingRow_CAY_2693() { + DataMap dataMap = new DataMap("map"); + + DbEntity dbEntity = new DbEntity("a"); + dbEntity.addAttribute(new DbAttribute("type")); + dataMap.addDbEntity(dbEntity); + + ObjEntity entityA = new ObjEntity("A"); + entityA.setAbstract(true); + entityA.setDbEntityName(dbEntity.getName()); + dataMap.addObjEntity(entityA); + + ObjEntity subEntityC = new ObjEntity("AC"); // name it AC so it would be sorted before B + subEntityC.setSuperEntityName("A"); + subEntityC.setAbstract(true); + dataMap.addObjEntity(subEntityC); + + ObjEntity subEntityB = new ObjEntity("B"); + subEntityB.setSuperEntityName("A"); + subEntityB.setDeclaredQualifier(ExpressionFactory.matchDbExp("type", 0)); + dataMap.addObjEntity(subEntityB); + + ObjEntity subEntityD = new ObjEntity("D"); + subEntityD.setSuperEntityName("AC"); + subEntityD.setDeclaredQualifier(ExpressionFactory.matchDbExp("type", 1)); + dataMap.addObjEntity(subEntityD); + + ObjEntity subEntityE = new ObjEntity("E"); + subEntityE.setSuperEntityName("AC"); + subEntityE.setDeclaredQualifier(ExpressionFactory.matchDbExp("type", 2)); + dataMap.addObjEntity(subEntityE); + + // creating EntityInheritanceTree via EntityResolver to ensure the entities are indexed + EntityResolver resolver = new EntityResolver(Collections.singleton(dataMap)); + EntityInheritanceTree treeA = resolver.getInheritanceTree("A"); + EntityInheritanceTree treeC = resolver.getInheritanceTree("AC"); + + DataRow row11 = new DataRow(5); + row11.put("type", 0); + + DataRow row12 = new DataRow(5); + row12.put("type", 1); + + DataRow row13 = new DataRow(5); + row13.put("type", 2); + + assertSame(subEntityB, treeA.entityMatchingRow(row11)); + assertSame(subEntityD, treeA.entityMatchingRow(row12)); + assertSame(subEntityE, treeA.entityMatchingRow(row13)); + + assertSame(subEntityD, treeC.entityMatchingRow(row12)); + assertSame(subEntityE, treeC.entityMatchingRow(row13)); + + assertNull(treeA.qualifierForEntityAndSubclasses()); + assertEquals(ExpressionFactory.exp("(db:type = 1) or (db:type = 2)"), treeC.qualifierForEntityAndSubclasses()); + } }