Repository: cayenne Updated Branches: refs/heads/master d5c47dee6 -> cd83358e7
CAY-2242 Vertical Inheritance: Cannot Insert Record With Multiple Flattened Relationships Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/cd83358e Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/cd83358e Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/cd83358e Branch: refs/heads/master Commit: cd83358e738c96db6f40b257efd339229950f6e1 Parents: d5c47de Author: Nikita Timofeev <stari...@gmail.com> Authored: Wed Feb 22 12:40:29 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Wed Feb 22 12:40:29 2017 +0300 ---------------------------------------------------------------------- .../access/DataDomainFlattenedBucket.java | 35 +++++++++++++------- .../cayenne/access/VerticalInheritanceIT.java | 28 ++++++++++++++-- .../inheritance_vertical/auto/_IvImpl.java | 27 ++++++++++++--- .../test/resources/inheritance-vertical.map.xml | 15 ++++++--- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + 5 files changed, 83 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/cd83358e/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java index fa3d3c9..b88a341 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java @@ -92,8 +92,6 @@ class DataDomainFlattenedBucket { * responsible for adding the flattened Insert Queries. Its possible an insert query for the same DbEntity/ObjectId * already has been added from the insert bucket queries if that Object also has an attribute. So we want to merge * the data for each insert into a single insert. - * - * @param queries */ void appendInserts(Collection<Query> queries) { @@ -110,24 +108,29 @@ class DataDomainFlattenedBucket { List<FlattenedArcKey> flattenedArcKeys = entry.getValue(); DataNode node = parent.getDomain().lookupDataNode(dbEntity.getDataMap()); - - // TODO: O(N) lookup - InsertBatchQuery existingQuery = findInsertBatchQuery(queries, dbEntity); InsertBatchQuery newQuery = new InsertBatchQuery(dbEntity, 50); + boolean newQueryAdded = false; + // Here can be options with multiple arcs: + // 1. they can go as different columns in a single row + // 2. they can go as different rows in one batch + // 3. mix of both for (FlattenedArcKey flattenedArcKey : flattenedArcKeys) { Map<String, Object> snapshot = flattenedArcKey.buildJoinSnapshotForInsert(node); + ObjectId objectId = null; + // TODO: O(N) lookup + InsertBatchQuery existingQuery = findInsertBatchQuery(queries, dbEntity); if (existingQuery != null) { - // TODO: O(N) lookup BatchQueryRow existingRow = findRowForObjectId(existingQuery.getRows(), flattenedArcKey.id1.getSourceId()); // todo: do we need to worry about flattenedArcKey.id2 ? if (existingRow != null) { + objectId = existingRow.getObjectId(); List<DbAttribute> existingQueryDbAttributes = existingQuery.getDbAttributes(); - for(int i=0; i < existingQueryDbAttributes.size(); i++) { + for (int i = 0; i < existingQueryDbAttributes.size(); i++) { Object value = existingRow.getValue(i); if (value != null) { snapshot.put(existingQueryDbAttributes.get(i).getName(), value); @@ -136,14 +139,22 @@ class DataDomainFlattenedBucket { } } - newQuery.add(snapshot); - } + newQuery.add(snapshot, objectId); - if (existingQuery != null) { - queries.remove(existingQuery); + if (existingQuery != null) { + // replace inside arc loop, so next arc know about it + queries.remove(existingQuery); + queries.add(newQuery); + newQueryAdded = true; + // start clean query for the next arc + newQuery = new InsertBatchQuery(dbEntity, 50); + } } - queries.add(newQuery); + if(!newQueryAdded) { + // if not replaced existing query already + queries.add(newQuery); + } } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/cd83358e/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java index 6abf403..1f2d512 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java @@ -20,6 +20,7 @@ package org.apache.cayenne.access; import org.apache.cayenne.ObjectContext; import org.apache.cayenne.di.Inject; +import org.apache.cayenne.query.ObjectSelect; import org.apache.cayenne.query.SelectQuery; import org.apache.cayenne.test.jdbc.DBHelper; import org.apache.cayenne.test.jdbc.TableHelper; @@ -27,6 +28,7 @@ import org.apache.cayenne.testdo.inheritance_vertical.*; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; +import org.apache.cayenne.validation.ValidationException; import org.junit.Test; import java.sql.SQLException; @@ -582,7 +584,7 @@ public class VerticalInheritanceIT extends ServerCase { context.commitChanges(); } - @Test + @Test(expected = ValidationException.class) // other2 is missing now public void testInsertWithAttributeAndRelationship() { IvOther other = context.newObject(IvOther.class); other.setName("other"); @@ -590,9 +592,31 @@ public class VerticalInheritanceIT extends ServerCase { IvImpl impl = context.newObject(IvImpl.class); impl.setName("Impl 1"); impl.setAttr1("attr1"); - impl.setOther(other); + impl.setOther1(other); + + context.commitChanges(); + } + + @Test + public void testInsertWithMultipleAttributeAndMultipleRelationship() { + IvOther other1 = context.newObject(IvOther.class); + other1.setName("other1"); + + IvOther other2 = context.newObject(IvOther.class); + other2.setName("other2"); + + IvImpl impl = context.newObject(IvImpl.class); + impl.setName("Impl 1"); + impl.setAttr1("attr1"); + impl.setAttr2("attr2"); + impl.setOther1(other1); + impl.setOther2(other2); context.commitChanges(); + + IvImpl impl2 = ObjectSelect.query(IvImpl.class).selectFirst(context); + assertEquals(other1, impl2.getOther1()); + assertEquals(other2, impl2.getOther2()); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/cd83358e/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvImpl.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvImpl.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvImpl.java index 4ce4c5c..421bae9 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvImpl.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvImpl.java @@ -17,7 +17,9 @@ public abstract class _IvImpl extends IvBase { public static final String ID_PK_COLUMN = "ID"; public static final Property<String> ATTR1 = Property.create("attr1", String.class); - public static final Property<IvOther> OTHER = Property.create("other", IvOther.class); + public static final Property<String> ATTR2 = Property.create("attr2", String.class); + public static final Property<IvOther> OTHER1 = Property.create("other1", IvOther.class); + public static final Property<IvOther> OTHER2 = Property.create("other2", IvOther.class); public void setAttr1(String attr1) { writeProperty("attr1", attr1); @@ -26,12 +28,27 @@ public abstract class _IvImpl extends IvBase { return (String)readProperty("attr1"); } - public void setOther(IvOther other) { - setToOneTarget("other", other, true); + public void setAttr2(String attr2) { + writeProperty("attr2", attr2); + } + public String getAttr2() { + return (String)readProperty("attr2"); + } + + public void setOther1(IvOther other1) { + setToOneTarget("other1", other1, true); + } + + public IvOther getOther1() { + return (IvOther)readProperty("other1"); + } + + public void setOther2(IvOther other2) { + setToOneTarget("other2", other2, true); } - public IvOther getOther() { - return (IvOther)readProperty("other"); + public IvOther getOther2() { + return (IvOther)readProperty("other2"); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/cd83358e/cayenne-server/src/test/resources/inheritance-vertical.map.xml ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/resources/inheritance-vertical.map.xml b/cayenne-server/src/test/resources/inheritance-vertical.map.xml index 35da2a5..694dc11 100644 --- a/cayenne-server/src/test/resources/inheritance-vertical.map.xml +++ b/cayenne-server/src/test/resources/inheritance-vertical.map.xml @@ -40,8 +40,10 @@ </db-entity> <db-entity name="IV_IMPL"> <db-attribute name="ATTR1" type="VARCHAR" isMandatory="true" length="100"/> + <db-attribute name="ATTR2" type="VARCHAR" isMandatory="true" length="100"/> <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/> - <db-attribute name="OTHER_ID" type="INTEGER" isMandatory="true"/> + <db-attribute name="OTHER1_ID" type="INTEGER" isMandatory="true"/> + <db-attribute name="OTHER2_ID" type="INTEGER" isMandatory="true"/> </db-entity> <db-entity name="IV_OTHER"> <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/> @@ -101,6 +103,7 @@ <obj-entity name="IvImpl" superEntityName="IvBase" className="org.apache.cayenne.testdo.inheritance_vertical.IvImpl"> <qualifier><![CDATA[type = "I"]]></qualifier> <obj-attribute name="attr1" type="java.lang.String" db-attribute-path="impl.ATTR1"/> + <obj-attribute name="attr2" type="java.lang.String" db-attribute-path="impl.ATTR2"/> </obj-entity> <obj-entity name="IvOther" className="org.apache.cayenne.testdo.inheritance_vertical.IvOther" dbEntityName="IV_OTHER"> <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/> @@ -167,8 +170,11 @@ <db-relationship name="base" source="IV_IMPL" target="IV_BASE" toMany="false"> <db-attribute-pair source="ID" target="ID"/> </db-relationship> - <db-relationship name="other" source="IV_IMPL" target="IV_OTHER" toMany="false"> - <db-attribute-pair source="OTHER_ID" target="ID"/> + <db-relationship name="other1" source="IV_IMPL" target="IV_OTHER" toMany="false"> + <db-attribute-pair source="OTHER1_ID" target="ID"/> + </db-relationship> + <db-relationship name="other2" source="IV_IMPL" target="IV_OTHER" toMany="false"> + <db-attribute-pair source="OTHER2_ID" target="ID"/> </db-relationship> <db-relationship name="impls" source="IV_OTHER" target="IV_IMPL" toMany="true"> <db-attribute-pair source="ID" target="OTHER_ID"/> @@ -206,7 +212,8 @@ <obj-relationship name="x" source="Iv2Sub1" target="Iv2X" deleteRule="Nullify" db-relationship-path="sub1.x"/> <obj-relationship name="children" source="IvConcrete" target="IvConcrete" deleteRule="Deny" db-relationship-path="children"/> <obj-relationship name="parent" source="IvConcrete" target="IvConcrete" deleteRule="Nullify" db-relationship-path="parent"/> - <obj-relationship name="other" source="IvImpl" target="IvOther" deleteRule="Nullify" db-relationship-path="impl.other"/> + <obj-relationship name="other1" source="IvImpl" target="IvOther" deleteRule="Nullify" db-relationship-path="impl.other1"/> + <obj-relationship name="other2" source="IvImpl" target="IvOther" deleteRule="Nullify" db-relationship-path="impl.other2"/> <obj-relationship name="impls" source="IvOther" target="IvImpl" deleteRule="Deny" db-relationship-path="impls.base"/> <obj-relationship name="ivRoot" source="IvSub3" target="IvRoot" deleteRule="Nullify" db-relationship-path="sub3.ivRoot1"/> <!--obj-relationship name="ivSub3ToRoot" source="IvSub3" target="IvRoot" deleteRule="Nullify" db-relationship-path="sub3"/--> http://git-wip-us.apache.org/repos/asf/cayenne/blob/cd83358e/docs/doc/src/main/resources/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt index 9e4e653..5bcddc4 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -47,6 +47,7 @@ CAY-2207 Modeler: "Java Type" and "DbAttribute Path" are not saved with using TA CAY-2221 In-memory expression evaluation gives different result than select query CAY-2236 Modeler Migrate DB Schema: unable to Reverse All Operations CAY-2238 Modeler: Preserve manually set DbRelationship name when syncing with ObjEntity +CAY-2242 Vertical Inheritance: Cannot Insert Record For Implementing Class with Attribute And Relationship ---------------------------------- Release: 4.0.M4