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 2020/10/02 15:28:32 UTC

[cayenne] branch STABLE-4.1 updated: Fix propagated DB-generated PK in the vertical inheritance

This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch STABLE-4.1
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/STABLE-4.1 by this push:
     new f62e5cb  Fix propagated DB-generated PK in the vertical inheritance
     new 0912731  Merge pull request #436 from stariy95/4.1-FIX-vertical-inheritance-generated-pk
f62e5cb is described below

commit f62e5cba22e2b7b7594d33cfdc4b34f4a8f5f972
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Fri Oct 2 17:56:32 2020 +0300

    Fix propagated DB-generated PK in the vertical inheritance
---
 .../cayenne/access/DataDomainDBDiffBuilder.java    |   2 +-
 .../cayenne/access/DataDomainInsertBucket.java     |   3 +
 .../cayenne/access/VerticalInheritanceIT.java      |  10 ++
 .../testdo/inheritance_vertical/IvGenKeyRoot.java  |   9 ++
 .../testdo/inheritance_vertical/IvGenKeySub.java   |   9 ++
 .../inheritance_vertical/auto/_IvGenKeyRoot.java   | 105 +++++++++++++++++++++
 .../inheritance_vertical/auto/_IvGenKeySub.java    |  66 +++++++++++++
 .../test/resources/inheritance-vertical.map.xml    |  23 +++++
 8 files changed, 226 insertions(+), 1 deletion(-)

diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
index 373334f..507a752 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
@@ -86,8 +86,8 @@ class DataDomainDBDiffBuilder implements GraphChangeHandler {
         Map<String, Object> dbDiff = new HashMap<>();
 
         appendSimpleProperties(dbDiff);
-        appendForeignKeys(dbDiff);
         appendPrimaryKeys(dbDiff);
+        appendForeignKeys(dbDiff);
 
         return dbDiff.isEmpty() ? null : dbDiff;
     }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
index e2b8500..89b1857 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
@@ -154,6 +154,9 @@ class DataDomainInsertBucket extends DataDomainSyncBucket {
 
                 // skip propagated
                 if (isPropagated(dbAttr)) {
+                    // this covers rare case of the DB-generated flattened PK,
+                    // for normal propagated PK this will be overwritten by the arc diff later
+                    idMap.put(dbAttrName, new PropagatedValueFactory(id, dbAttrName));
                     continue;
                 }
 
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 3cfe989..5ae52ab 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
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.access;
 
+import org.apache.cayenne.Cayenne;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.di.Inject;
@@ -676,4 +677,13 @@ public class VerticalInheritanceIT extends ServerCase {
 		EJBQLQuery query3 = new EJBQLQuery("SELECT COUNT(a) FROM IvSub2 a");
 		assertEquals(Collections.singletonList(2L), context.performQuery(query3));
 	}
+
+	@Test
+	public void testPropagatedGeneratedPK() {
+		IvGenKeySub sub = context.newObject(IvGenKeySub.class);
+		sub.setName("test");
+		context.commitChanges();
+
+		assertTrue(Cayenne.intPKForObject(sub) > 0);
+	}
 }
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeyRoot.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeyRoot.java
new file mode 100644
index 0000000..c407be3
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeyRoot.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.inheritance_vertical;
+
+import org.apache.cayenne.testdo.inheritance_vertical.auto._IvGenKeyRoot;
+
+public class IvGenKeyRoot extends _IvGenKeyRoot {
+
+    private static final long serialVersionUID = 1L; 
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeySub.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeySub.java
new file mode 100644
index 0000000..c58b953
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvGenKeySub.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.inheritance_vertical;
+
+import org.apache.cayenne.testdo.inheritance_vertical.auto._IvGenKeySub;
+
+public class IvGenKeySub extends _IvGenKeySub {
+
+    private static final long serialVersionUID = 1L; 
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeyRoot.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeyRoot.java
new file mode 100644
index 0000000..bfd0ba9
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeyRoot.java
@@ -0,0 +1,105 @@
+package org.apache.cayenne.testdo.inheritance_vertical.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _IvGenKeyRoot was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _IvGenKeyRoot extends BaseDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<String> DISCRIMINATOR = Property.create("discriminator", String.class);
+    public static final Property<String> NAME = Property.create("name", String.class);
+
+    protected String discriminator;
+    protected String name;
+
+
+    public void setDiscriminator(String discriminator) {
+        beforePropertyWrite("discriminator", this.discriminator, discriminator);
+        this.discriminator = discriminator;
+    }
+
+    public String getDiscriminator() {
+        beforePropertyRead("discriminator");
+        return this.discriminator;
+    }
+
+    public void setName(String name) {
+        beforePropertyWrite("name", this.name, name);
+        this.name = name;
+    }
+
+    public String getName() {
+        beforePropertyRead("name");
+        return this.name;
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "discriminator":
+                return this.discriminator;
+            case "name":
+                return this.name;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "discriminator":
+                this.discriminator = (String)val;
+                break;
+            case "name":
+                this.name = (String)val;
+                break;
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+        out.writeObject(this.discriminator);
+        out.writeObject(this.name);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        super.readState(in);
+        this.discriminator = (String)in.readObject();
+        this.name = (String)in.readObject();
+    }
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeySub.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeySub.java
new file mode 100644
index 0000000..62d5345
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvGenKeySub.java
@@ -0,0 +1,66 @@
+package org.apache.cayenne.testdo.inheritance_vertical.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.testdo.inheritance_vertical.IvGenKeyRoot;
+
+/**
+ * Class _IvGenKeySub was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _IvGenKeySub extends IvGenKeyRoot {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "ID";
+
+
+
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        super.readState(in);
+    }
+
+}
diff --git a/cayenne-server/src/test/resources/inheritance-vertical.map.xml b/cayenne-server/src/test/resources/inheritance-vertical.map.xml
index 2714b8f..15d8d66 100644
--- a/cayenne-server/src/test/resources/inheritance-vertical.map.xml
+++ b/cayenne-server/src/test/resources/inheritance-vertical.map.xml
@@ -43,6 +43,15 @@
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
 		<db-attribute name="NAME" type="VARCHAR" length="100"/>
 	</db-entity>
+	<db-entity name="IV_GEN_KEY_ROOT">
+		<db-attribute name="DISCRIMINATOR" type="VARCHAR" length="10"/>
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="IV_GEN_KEY_SUB">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="SUB1_NAME" type="VARCHAR" length="100"/>
+	</db-entity>
 	<db-entity name="IV_IMPL">
 		<db-attribute name="ATTR1" type="VARCHAR" length="100"/>
 		<db-attribute name="ATTR2" type="VARCHAR" length="100"/>
@@ -112,6 +121,14 @@
 		<qualifier><![CDATA[type = "S"]]></qualifier>
 		<obj-attribute name="name" type="java.lang.String" db-attribute-path="concrete.NAME"/>
 	</obj-entity>
+	<obj-entity name="IvGenKeyRoot" className="org.apache.cayenne.testdo.inheritance_vertical.IvGenKeyRoot" dbEntityName="IV_GEN_KEY_ROOT">
+		<obj-attribute name="discriminator" type="java.lang.String" db-attribute-path="DISCRIMINATOR"/>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+	</obj-entity>
+	<obj-entity name="IvGenKeySub" superEntityName="IvGenKeyRoot" className="org.apache.cayenne.testdo.inheritance_vertical.IvGenKeySub">
+		<qualifier><![CDATA[discriminator = "sub1"]]></qualifier>
+		<attribute-override name="name" db-attribute-path="sub1.SUB1_NAME"/>
+	</obj-entity>
 	<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"/>
@@ -185,6 +202,12 @@
 	<db-relationship name="abstract" source="IV_CONCRETE" target="IV_ABSTRACT">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
+	<db-relationship name="sub1" source="IV_GEN_KEY_ROOT" target="IV_GEN_KEY_SUB" toDependentPK="true">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="root" source="IV_GEN_KEY_SUB" target="IV_GEN_KEY_ROOT">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
 	<db-relationship name="base" source="IV_IMPL" target="IV_BASE">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>