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 <stari...@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>