You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/22 09:40:52 UTC

cayenne git commit: CAY-2242 Vertical Inheritance: Cannot Insert Record With Multiple Flattened Relationships

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 <st...@gmail.com>
Authored: Wed Feb 22 12:40:29 2017 +0300
Committer: Nikita Timofeev <st...@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