You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/11/27 13:42:20 UTC

[1/4] cayenne git commit: CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails

Repository: cayenne
Updated Branches:
  refs/heads/master 1b56fe6f6 -> 0e3a07c1e


CAY-2146
Vertical inheritance: record still inserted into parent db table when child validation fails


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/2df9ae8f
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/2df9ae8f
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/2df9ae8f

Branch: refs/heads/master
Commit: 2df9ae8f69a4f50d597f2afa58a205783882a21d
Parents: b0d0faf
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Nov 18 12:33:33 2016 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Nov 18 12:33:33 2016 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/CayenneDataObject.java   |  42 +++---
 .../cayenne/access/VerticalInheritanceIT.java   |  41 +++++
 .../testdo/inheritance_vertical/IvSub3.java     |  15 ++
 .../inheritance_vertical/auto/_IvSub3.java      |  30 ++++
 .../test/resources/inheritance-vertical.map.xml | 150 +++++++++++--------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 6 files changed, 194 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
index 3b0f9d0..d61b33f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
@@ -655,39 +655,37 @@ public class CayenneDataObject extends PersistentObject implements DataObject, V
 		// validate mandatory relationships
 		for (final ObjRelationship relationship : objEntity.getRelationships()) {
 
-			if (relationship.isSourceIndependentFromTargetChange()) {
+			List<DbRelationship> dbRels = relationship.getDbRelationships();
+			if (dbRels.isEmpty()) {
 				continue;
 			}
 
-			List<DbRelationship> dbRels = relationship.getDbRelationships();
-			if (dbRels.isEmpty()) {
+			// skip db relationships that we can't validate or that can't be invalid here
+			// can't handle paths longer than two db relationships
+			// see ObjRelationship.recalculateReadOnlyValue() for more info
+			if (dbRels.size() == 1 && relationship.isSourceIndependentFromTargetChange() ||
+					dbRels.size() > 1 && (relationship.isToMany() || relationship.isReadOnly())) {
 				continue;
 			}
 
 			// if db relationship is not based on a PK and is based on mandatory
 			// attributes, see if we have a target object set
+			// relationship will be validated only if all db path has mandatory
+			// db relationships
 			boolean validate = true;
-			DbRelationship dbRelationship = dbRels.get(0);
-			for (DbJoin join : dbRelationship.getJoins()) {
-				DbAttribute source = join.getSource();
-
-				if (source.isMandatory()) {
-					// clear attribute failures...
-					if (failedDbAttributes != null && !failedDbAttributes.isEmpty()) {
-						failedDbAttributes.remove(source.getName());
-
-						// loop through all joins if there were previous
-						// mandatory
-
-						// attribute failures....
-						if (!failedDbAttributes.isEmpty()) {
-							continue;
+			for (DbRelationship dbRelationship : dbRels) {
+				for (DbJoin join : dbRelationship.getJoins()) {
+					DbAttribute source = join.getSource();
+					if (source.isMandatory()) {
+						// clear attribute failures...
+						if (failedDbAttributes != null && !failedDbAttributes.isEmpty()) {
+							failedDbAttributes.remove(source.getName());
 						}
+					} else {
+						// do not validate if the relation is based on
+						// multiple keys with some that can be nullable.
+						validate = false;
 					}
-				} else {
-					// do not validate if the relation is based on
-					// multiple keys with some that can be nullable.
-					validate = false;
 				}
 			}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/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 c5109a4..5a1e957 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
@@ -187,6 +187,47 @@ public class VerticalInheritanceIT extends ServerCase {
 		assertEquals(0, ivSub2Table.getRowCount());
 	}
 
+	/**
+	 * @link https://issues.apache.org/jira/browse/CAY-2146
+	 */
+    @Test(expected = org.apache.cayenne.validation.ValidationException.class)
+    public void testValidationOnInsert_Sub3_Exception() throws Exception {
+
+        TableHelper ivRootTable = new TableHelper(dbHelper, "IV_ROOT");
+        ivRootTable.setColumns("ID", "NAME", "DISCRIMINATOR");
+
+        TableHelper ivSub3Table = new TableHelper(dbHelper, "IV_SUB3");
+        ivSub3Table.setColumns("ID", "IV_ROOT_ID");
+
+        IvSub3 sub3 = context.newObject(IvSub3.class);
+        sub3.setName("XyZX");
+		context.commitChanges();
+
+        assertEquals(1, ivRootTable.getRowCount());
+        assertEquals(1, ivSub3Table.getRowCount());
+    }
+
+	/**
+	 * @link https://issues.apache.org/jira/browse/CAY-2146
+	 */
+	@Test
+	public void testValidationOnInsert_Sub3_Ok() throws Exception {
+
+		TableHelper ivRootTable = new TableHelper(dbHelper, "IV_ROOT");
+		ivRootTable.setColumns("ID", "NAME", "DISCRIMINATOR");
+
+		TableHelper ivSub3Table = new TableHelper(dbHelper, "IV_SUB3");
+		ivSub3Table.setColumns("ID", "IV_ROOT_ID");
+
+		IvSub3 sub3 = context.newObject(IvSub3.class);
+		sub3.setName("XyZX");
+		sub3.setIvRoot(sub3);
+		context.commitChanges();
+
+		assertEquals(1, ivRootTable.getRowCount());
+		assertEquals(1, ivSub3Table.getRowCount());
+	}
+
     @Test
 	public void testInsert_Sub1Sub1() throws Exception {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvSub3.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvSub3.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvSub3.java
new file mode 100644
index 0000000..3fda8b5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/IvSub3.java
@@ -0,0 +1,15 @@
+package org.apache.cayenne.testdo.inheritance_vertical;
+
+import org.apache.cayenne.testdo.inheritance_vertical.auto._IvSub3;
+
+public class IvSub3 extends _IvSub3 {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void onPrePersist() {
+//        if(getIvRoot() == null) {
+//            throw new IllegalStateException("IvRoot must be set");
+//        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvSub3.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvSub3.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvSub3.java
new file mode 100644
index 0000000..16b4edf
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_vertical/auto/_IvSub3.java
@@ -0,0 +1,30 @@
+package org.apache.cayenne.testdo.inheritance_vertical.auto;
+
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.inheritance_vertical.IvRoot;
+
+/**
+ * Class _IvSub3 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 _IvSub3 extends IvRoot {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<IvRoot> IV_ROOT = new Property<IvRoot>("ivRoot");
+
+    public void setIvRoot(IvRoot ivRoot) {
+        setToOneTarget("ivRoot", ivRoot, true);
+    }
+
+    public IvRoot getIvRoot() {
+        return (IvRoot)readProperty("ivRoot");
+    }
+
+    protected abstract void onPrePersist();
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/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 27b9c9b..35da2a5 100644
--- a/cayenne-server/src/test/resources/inheritance-vertical.map.xml
+++ b/cayenne-server/src/test/resources/inheritance-vertical.map.xml
@@ -24,54 +24,52 @@
 	<db-entity name="IV2_X">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
 	</db-entity>
-	<db-entity name="IV_ROOT">
-		<db-attribute name="DISCRIMINATOR" type="VARCHAR" length="10"/>
+	<db-entity name="IV_ABSTRACT">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="PARENT_ID" type="INTEGER"/>
+		<db-attribute name="TYPE" type="CHAR" isMandatory="true" length="1"/>
 	</db-entity>
-	<db-entity name="IV_SUB1">
+	<db-entity name="IV_BASE">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SUB1_NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+		<db-attribute name="TYPE" type="CHAR" isMandatory="true" length="1"/>
 	</db-entity>
-	<db-entity name="IV_SUB1_SUB1">
+	<db-entity name="IV_CONCRETE">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SUB1_SUB1_NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
 	</db-entity>
-	<db-entity name="IV_SUB2">
+	<db-entity name="IV_IMPL">
+		<db-attribute name="ATTR1" type="VARCHAR" isMandatory="true" length="100"/>
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="SUB2_ATTR" type="VARCHAR" length="100"/>
-		<db-attribute name="SUB2_NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="OTHER_ID" type="INTEGER" isMandatory="true"/>
 	</db-entity>
-	<db-entity name="IV_CONCRETE">
+	<db-entity name="IV_OTHER">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
 		<db-attribute name="NAME" type="VARCHAR" length="100"/>
 	</db-entity>
-	<db-entity name="IV_ABSTRACT">
-		<db-attribute name="PARENT_ID" type="INTEGER"/>
-		<db-attribute name="TYPE" type="CHAR" isMandatory="true" length="1"/>
+	<db-entity name="IV_ROOT">
+		<db-attribute name="DISCRIMINATOR" type="VARCHAR" length="10"/>
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="NAME" type="VARCHAR" length="100"/>
 	</db-entity>
-	<db-entity name="IV_OTHER">
+	<db-entity name="IV_SUB1">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100"/>
+		<db-attribute name="SUB1_NAME" type="VARCHAR" length="100"/>
 	</db-entity>
-	<db-entity name="IV_BASE">
-		<db-attribute name="TYPE" type="CHAR" isMandatory="true" length="1"/>
+	<db-entity name="IV_SUB1_SUB1">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="NAME" type="VARCHAR" length="100" isMandatory="true"/>
+		<db-attribute name="SUB1_SUB1_NAME" type="VARCHAR" length="100"/>
 	</db-entity>
-	<db-entity name="IV_IMPL">
+	<db-entity name="IV_SUB2">
 		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
-		<db-attribute name="ATTR1" type="VARCHAR" length="100" isMandatory="true"/>
-		<db-attribute name="OTHER_ID" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="SUB2_ATTR" type="VARCHAR" length="100"/>
+		<db-attribute name="SUB2_NAME" type="VARCHAR" length="100"/>
+	</db-entity>
+	<db-entity name="IV_SUB3">
+		<db-attribute name="ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+		<!--db-attribute name="SUB3_ATTR" type="INTEGER"/-->
+		<db-attribute name="IV_ROOT_ID" type="INTEGER" isMandatory="true"/>
 	</db-entity>
-	<obj-entity name="IvConcrete" superEntityName="IvAbstract" className="org.apache.cayenne.testdo.inheritance_vertical.IvConcrete">
-		<qualifier><![CDATA[type = "S"]]></qualifier>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="concrete.NAME"/>
-	</obj-entity>
-	<obj-entity name="IvAbstract" abstract="true" className="org.apache.cayenne.testdo.inheritance_vertical.IvAbstract" dbEntityName="IV_ABSTRACT">
-		<obj-attribute name="type" type="java.lang.String" db-attribute-path="TYPE"/>
-	</obj-entity>
 	<obj-entity name="Iv1Root" className="org.apache.cayenne.testdo.inheritance_vertical.Iv1Root" dbEntityName="IV1_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"/>
@@ -89,6 +87,24 @@
 	</obj-entity>
 	<obj-entity name="Iv2X" className="org.apache.cayenne.testdo.inheritance_vertical.Iv2X" dbEntityName="IV2_X">
 	</obj-entity>
+	<obj-entity name="IvAbstract" abstract="true" className="org.apache.cayenne.testdo.inheritance_vertical.IvAbstract" dbEntityName="IV_ABSTRACT">
+		<obj-attribute name="type" type="java.lang.String" db-attribute-path="TYPE"/>
+	</obj-entity>
+	<obj-entity name="IvBase" abstract="true" className="org.apache.cayenne.testdo.inheritance_vertical.IvBase" dbEntityName="IV_BASE">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+		<obj-attribute name="type" type="java.lang.String" db-attribute-path="TYPE"/>
+	</obj-entity>
+	<obj-entity name="IvConcrete" superEntityName="IvAbstract" className="org.apache.cayenne.testdo.inheritance_vertical.IvConcrete">
+		<qualifier><![CDATA[type = "S"]]></qualifier>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="concrete.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"/>
+	</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"/>
+	</obj-entity>
 	<obj-entity name="IvRoot" className="org.apache.cayenne.testdo.inheritance_vertical.IvRoot" dbEntityName="IV_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"/>
@@ -110,29 +126,11 @@
 		<obj-attribute name="sub2Attr" type="java.lang.String" db-attribute-path="sub2.SUB2_ATTR"/>
 		<obj-attribute name="sub2Name" type="java.lang.String" db-attribute-path="sub2.SUB2_NAME"/>
 	</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"/>
-	</obj-entity>
-	<obj-entity name="IvBase" abstract="true" className="org.apache.cayenne.testdo.inheritance_vertical.IvBase" dbEntityName="IV_BASE">
-		<obj-attribute name="type" type="java.lang.String" db-attribute-path="TYPE"/>
-		<obj-attribute name="name" type="java.lang.String" db-attribute-path="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"/>
+	<obj-entity name="IvSub3" superEntityName="IvRoot" className="org.apache.cayenne.testdo.inheritance_vertical.IvSub3">
+		<qualifier><![CDATA[discriminator = "IvSub3"]]></qualifier>
+		<!--obj-attribute name="sub3Attr" type="int" db-attribute-path="sub3.SUB3_ATTR"/-->
+		<!--pre-persist method-name="onPrePersist"/-->
 	</obj-entity>
-	<db-relationship name="abstract" source="IV_CONCRETE" target="IV_ABSTRACT" toMany="false">
-		<db-attribute-pair source="ID" target="ID"/>
-	</db-relationship>
-	<db-relationship name="concrete" source="IV_ABSTRACT" target="IV_CONCRETE" toDependentPK="true" toMany="false">
-		<db-attribute-pair source="ID" target="ID"/>
-	</db-relationship>
-	<db-relationship name="parent" source="IV_ABSTRACT" target="IV_ABSTRACT" toMany="false">
-		<db-attribute-pair source="PARENT_ID" target="ID"/>
-	</db-relationship>
-	<db-relationship name="children" source="IV_ABSTRACT" target="IV_ABSTRACT" toMany="true">
-		<db-attribute-pair source="ID" target="PARENT_ID"/>
-	</db-relationship>
 	<db-relationship name="sub1" source="IV1_ROOT" target="IV1_SUB1" toDependentPK="true" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
@@ -151,12 +149,42 @@
 	<db-relationship name="sub1" source="IV2_X" target="IV2_SUB1" toMany="true">
 		<db-attribute-pair source="ID" target="X_ID"/>
 	</db-relationship>
+	<db-relationship name="children" source="IV_ABSTRACT" target="IV_ABSTRACT" toMany="true">
+		<db-attribute-pair source="ID" target="PARENT_ID"/>
+	</db-relationship>
+	<db-relationship name="concrete" source="IV_ABSTRACT" target="IV_CONCRETE" toDependentPK="true" toMany="false">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="parent" source="IV_ABSTRACT" target="IV_ABSTRACT" toMany="false">
+		<db-attribute-pair source="PARENT_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="impl" source="IV_BASE" target="IV_IMPL" toDependentPK="true" toMany="false">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="abstract" source="IV_CONCRETE" target="IV_ABSTRACT" toMany="false">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
+	<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>
+	<db-relationship name="impls" source="IV_OTHER" target="IV_IMPL" toMany="true">
+		<db-attribute-pair source="ID" target="OTHER_ID"/>
+	</db-relationship>
+	<db-relationship name="ivSub3s" source="IV_ROOT" target="IV_SUB3" toMany="true">
+		<db-attribute-pair source="ID" target="IV_ROOT_ID"/>
+	</db-relationship>
 	<db-relationship name="sub1" source="IV_ROOT" target="IV_SUB1" toDependentPK="true" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
 	<db-relationship name="sub2" source="IV_ROOT" target="IV_SUB2" toDependentPK="true" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
+	<db-relationship name="sub3" source="IV_ROOT" target="IV_SUB3" toDependentPK="true" toMany="false">
+		<db-attribute-pair source="ID" target="ID"/>
+	</db-relationship>
 	<db-relationship name="master" source="IV_SUB1" target="IV_ROOT" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
@@ -166,24 +194,20 @@
 	<db-relationship name="master" source="IV_SUB1_SUB1" target="IV_SUB1" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
+	<!--db-relationship name="ivSub3s1" source="IV_SUB2" target="IV_SUB3" toMany="true">
+		<db-attribute-pair source="ID" target="IV_ROOT_ID"/>
+	</db-relationship-->
 	<db-relationship name="master" source="IV_SUB2" target="IV_ROOT" toMany="false">
 		<db-attribute-pair source="ID" target="ID"/>
 	</db-relationship>
-	<db-relationship name="impl" source="IV_BASE" target="IV_IMPL" toDependentPK="true" toMany="false">
-		<db-attribute-pair source="ID" target="ID"/>
-	</db-relationship>
-	<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>
-	<db-relationship name="impls" source="IV_OTHER" target="IV_IMPL" toMany="true">
-		<db-attribute-pair source="ID" target="OTHER_ID"/>
+	<db-relationship name="ivRoot1" source="IV_SUB3" target="IV_ROOT" toMany="false">
+		<db-attribute-pair source="IV_ROOT_ID" target="ID"/>
 	</db-relationship>
 	<obj-relationship name="x" source="Iv2Sub1" target="Iv2X" deleteRule="Nullify" db-relationship-path="sub1.x"/>
-	<obj-relationship name="parent" source="IvConcrete" target="IvConcrete" deleteRule="Nullify" db-relationship-path="parent"/>
 	<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="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"/-->
 </data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2df9ae8f/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 eaca48f..ade50fb 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -68,6 +68,7 @@ CAY-2128 Modeler stored procedures are not imported
 CAY-2131 Modeler NullPointerException in reverse engineering when importing different catalogs in one datamap
 CAY-2138 NVARCHAR, LONGNVARCHAR and NCLOB types are missing from Firebird types.xml
 CAY-2143 NPE in BaseSchemaUpdateStrategy
+CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails
 
 ----------------------------------
 Release: 4.0.M3


[3/4] cayenne git commit: Merge branch '137'

Posted by aa...@apache.org.
Merge branch '137'


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/b2173133
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/b2173133
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/b2173133

Branch: refs/heads/master
Commit: b21731338ae3812db1e0906be9c9c604474a5729
Parents: 1b56fe6 7fbcc01
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Sun Nov 27 16:03:11 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Sun Nov 27 16:03:11 2016 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/CayenneDataObject.java   |  42 +++---
 .../cayenne/access/VerticalInheritanceIT.java   |  41 +++++
 .../testdo/inheritance_vertical/IvSub3.java     |  15 ++
 .../inheritance_vertical/auto/_IvSub3.java      |  30 ++++
 .../test/resources/inheritance-vertical.map.xml | 150 +++++++++++--------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 6 files changed, 194 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/b2173133/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --cc docs/doc/src/main/resources/RELEASE-NOTES.txt
index 5dbdc64,b07f826..5cf1320
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@@ -69,10 -69,7 +69,11 @@@ CAY-2131 Modeler NullPointerException i
  CAY-2138 NVARCHAR, LONGNVARCHAR and NCLOB types are missing from Firebird types.xml
  CAY-2143 NPE in BaseSchemaUpdateStrategy
  CAY-2144 cdbimport always fails for databases which don't support catalogs
+ CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails
 +CAY-2148 Failure upgrading from 3.1 to M4
 +CAY-2150 UI bug: PK generation custom sequence is getting reset
 +CAY-2153 Modeler Exception in save action after reverse engineering some complex DB schema
 +CAY-2154 Migrate db: queries order
  
  ----------------------------------
  Release: 4.0.M3


[4/4] cayenne git commit: CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails

Posted by aa...@apache.org.
CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails

* no changes; minor refactoring for clarity


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0e3a07c1
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0e3a07c1
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0e3a07c1

Branch: refs/heads/master
Commit: 0e3a07c1ec1f97938b7d0d9c67512dbd4a75f86c
Parents: b217313
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Sun Nov 27 16:36:44 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Sun Nov 27 16:36:44 2016 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/CayenneDataObject.java   | 29 +++++++++++---------
 .../cayenne/access/VerticalInheritanceIT.java   |  3 --
 2 files changed, 16 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e3a07c1/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
index d61b33f..3b7a5be 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/CayenneDataObject.java
@@ -19,17 +19,6 @@
 
 package org.apache.cayenne;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
@@ -43,6 +32,17 @@ import org.apache.cayenne.validation.BeanValidationFailure;
 import org.apache.cayenne.validation.ValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
 /**
  * A default implementation of DataObject interface. It is normally used as a
  * superclass of Cayenne persistent objects.
@@ -663,8 +663,11 @@ public class CayenneDataObject extends PersistentObject implements DataObject, V
 			// skip db relationships that we can't validate or that can't be invalid here
 			// can't handle paths longer than two db relationships
 			// see ObjRelationship.recalculateReadOnlyValue() for more info
-			if (dbRels.size() == 1 && relationship.isSourceIndependentFromTargetChange() ||
-					dbRels.size() > 1 && (relationship.isToMany() || relationship.isReadOnly())) {
+			if (dbRels.size() == 1 && relationship.isSourceIndependentFromTargetChange()) {
+				continue;
+			}
+
+			if (dbRels.size() > 1 && (relationship.isToMany() || relationship.isReadOnly())) {
 				continue;
 			}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e3a07c1/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 5a1e957..6abf403 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
@@ -202,9 +202,6 @@ public class VerticalInheritanceIT extends ServerCase {
         IvSub3 sub3 = context.newObject(IvSub3.class);
         sub3.setName("XyZX");
 		context.commitChanges();
-
-        assertEquals(1, ivRootTable.getRowCount());
-        assertEquals(1, ivSub3Table.getRowCount());
     }
 
 	/**


[2/4] cayenne git commit: Merge branch 'master' into CAY-2146

Posted by aa...@apache.org.
Merge branch 'master' into CAY-2146

# Conflicts:
#	docs/doc/src/main/resources/RELEASE-NOTES.txt


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/7fbcc016
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/7fbcc016
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/7fbcc016

Branch: refs/heads/master
Commit: 7fbcc016c6425d539dc33a25165992d9b1f31cb6
Parents: 2df9ae8 f527275
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Nov 22 14:14:48 2016 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Tue Nov 22 14:14:48 2016 +0300

----------------------------------------------------------------------
 .../apache/cayenne/reflect/BeanAccessor.java    | 14 ++--
 .../tools/DbImportConfigurationValidator.java   | 87 ++++++++++++++++++++
 .../apache/cayenne/tools/DbImporterTask.java    | 47 ++++-------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |  1 +
 .../apache/cayenne/tools/DbImporterMojo.java    | 37 ++-------
 5 files changed, 122 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7fbcc016/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --cc docs/doc/src/main/resources/RELEASE-NOTES.txt
index ade50fb,b6e2f8b..b07f826
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@@ -68,7 -68,7 +68,8 @@@ CAY-2128 Modeler stored procedures are 
  CAY-2131 Modeler NullPointerException in reverse engineering when importing different catalogs in one datamap
  CAY-2138 NVARCHAR, LONGNVARCHAR and NCLOB types are missing from Firebird types.xml
  CAY-2143 NPE in BaseSchemaUpdateStrategy
+ CAY-2144 cdbimport always fails for databases which don't support catalogs
 +CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails
  
  ----------------------------------
  Release: 4.0.M3