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 2021/03/26 14:54:44 UTC
[cayenne] branch master updated: CAY-2704 Vertical inheritance with
Embeddedables looses ObjAttribute information
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new 16d61ac CAY-2704 Vertical inheritance with Embeddedables looses ObjAttribute information
16d61ac is described below
commit 16d61acf01fefd2e1a6f2d31440c10863406510f
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Fri Mar 26 17:54:35 2021 +0300
CAY-2704 Vertical inheritance with Embeddedables looses ObjAttribute information
---
.../org/apache/cayenne/map/EmbeddedAttribute.java | 24 ++++--
.../java/org/apache/cayenne/map/ObjEntity.java | 27 +++++--
.../org/apache/cayenne/access/EmbeddingIT.java | 62 +++++++++++++++
.../cayenne/testdo/embeddable/EmbedChild.java | 9 +++
.../cayenne/testdo/embeddable/EmbedRoot.java | 9 +++
.../testdo/embeddable/auto/_EmbedChild.java | 87 ++++++++++++++++++++++
.../testdo/embeddable/auto/_EmbedEntity1.java | 2 +-
.../testdo/embeddable/auto/_EmbedEntity2.java | 2 +-
.../auto/{_EmbedEntity2.java => _EmbedRoot.java} | 35 ++++-----
.../src/test/resources/embeddable.map.xml | 27 +++++++
10 files changed, 252 insertions(+), 32 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/EmbeddedAttribute.java b/cayenne-server/src/main/java/org/apache/cayenne/map/EmbeddedAttribute.java
index a3d99ef..6acad57 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/EmbeddedAttribute.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/EmbeddedAttribute.java
@@ -54,6 +54,21 @@ public class EmbeddedAttribute extends ObjAttribute {
setEntity(entity);
}
+ /**
+ * Copying constructor
+ * @param other attribute to copy
+ * @since 4.2
+ */
+ public EmbeddedAttribute(EmbeddedAttribute other) {
+ setName(other.getName());
+ setType(other.getType());
+ setEntity(other.getEntity());
+ setDbAttributePath(other.getDbAttributePath());
+ setUsedForLocking(other.isUsedForLocking());
+ setLazy(other.isLazy());
+ attributeOverrides = other.getAttributeOverrides();
+ }
+
@Override
public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
encoder.start("embedded-attribute")
@@ -91,15 +106,10 @@ public class EmbeddedAttribute extends ObjAttribute {
return makeObjAttribute(embeddableAttribute, dbPath);
}
- private ObjAttribute makeObjAttribute(
- EmbeddableAttribute embeddableAttribute,
- String dbPath) {
+ private ObjAttribute makeObjAttribute(EmbeddableAttribute embeddableAttribute, String dbPath) {
String fullName = getName() + "." + embeddableAttribute.getName();
- ObjAttribute oa = new ObjAttribute(
- fullName,
- embeddableAttribute.getType(),
- (ObjEntity) getEntity());
+ ObjAttribute oa = new ObjAttribute(fullName, embeddableAttribute.getType(), getEntity());
oa.setDbAttributePath(dbPath);
return oa;
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
index 47ea965..a59065c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
@@ -32,6 +32,8 @@ import org.apache.cayenne.map.event.ObjEntityListener;
import org.apache.cayenne.util.CayenneMapEntry;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.util.XMLEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
@@ -52,11 +54,12 @@ import java.util.function.Function;
*/
public class ObjEntity extends Entity implements ObjEntityListener, ConfigurationNode {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ObjEntity.class);
+
public static final int LOCK_TYPE_NONE = 0;
public static final int LOCK_TYPE_OPTIMISTIC = 1;
- // do not import CayenneDataObject as it introduces unneeded client
- // dependency
+ // do not import CayenneDataObject as it introduces unneeded client dependency
private static final String CAYENNE_DATA_OBJECT_CLASS = "org.apache.cayenne.CayenneDataObject";
/**
* A collection of default "generic" entity classes excluded from class
@@ -641,11 +644,23 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
String overridedDbPath = attributeOverrides.get(attributeName);
- ObjAttribute attribute = new ObjAttribute(attributeMap.get(attributeName));
- attribute.setEntity(this);
- if (overridedDbPath != null) {
- attribute.setDbAttributePath(overridedDbPath);
+ ObjAttribute superAttribute = attributeMap.get(attributeName);
+ ObjAttribute attribute;
+
+ if(superAttribute instanceof EmbeddedAttribute) {
+ EmbeddedAttribute embeddedAttribute = new EmbeddedAttribute((EmbeddedAttribute)superAttribute);
+ if(overridedDbPath != null) {
+ LOGGER.warn("'{}.{}': DB path override for an embedded attribute is not supported.",
+ getName(), attributeName);
+ }
+ attribute = embeddedAttribute;
+ } else {
+ attribute = new ObjAttribute(superAttribute);
+ if (overridedDbPath != null) {
+ attribute.setDbAttributePath(overridedDbPath);
+ }
}
+ attribute.setEntity(this);
map.put(attributeName, attribute);
}
}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
index 0f3f291..c01f363 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/EmbeddingIT.java
@@ -25,8 +25,10 @@ import org.apache.cayenne.di.Inject;
import org.apache.cayenne.query.ObjectSelect;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.embeddable.EmbedChild;
import org.apache.cayenne.testdo.embeddable.EmbedEntity1;
import org.apache.cayenne.testdo.embeddable.EmbedEntity2;
+import org.apache.cayenne.testdo.embeddable.EmbedRoot;
import org.apache.cayenne.testdo.embeddable.Embeddable1;
import org.apache.cayenne.unit.di.server.CayenneProjects;
import org.apache.cayenne.unit.di.server.ServerCase;
@@ -38,6 +40,7 @@ import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
@UseServerRuntime(CayenneProjects.EMBEDDABLE_PROJECT)
public class EmbeddingIT extends ServerCase {
@@ -50,6 +53,8 @@ public class EmbeddingIT extends ServerCase {
protected TableHelper tEmbedEntity1;
protected TableHelper tEmbedEntity2;
+ protected TableHelper tEmbedRoot;
+ protected TableHelper tEmbedChild;
@Before
public void setUp() throws Exception {
@@ -58,6 +63,12 @@ public class EmbeddingIT extends ServerCase {
tEmbedEntity2 = new TableHelper(dbHelper, "EMBED_ENTITY2");
tEmbedEntity2.setColumns("ID", "NAME", "ENTITY1_ID", "EMBEDDED10", "EMBEDDED20");
+
+ tEmbedRoot = new TableHelper(dbHelper, "EMBED_ROOT");
+ tEmbedRoot.setColumns("ID", "NAME", "EMBEDDED10", "EMBEDDED20", "TYPE");
+
+ tEmbedChild = new TableHelper(dbHelper, "EMBED_CHILD");
+ tEmbedChild.setColumns("ID", "CHILD_ATTR");
}
protected void createSelectDataSet() throws Exception {
@@ -71,6 +82,12 @@ public class EmbeddingIT extends ServerCase {
tEmbedEntity2.insert(2, "n2-1", 2, "e1", "e2");
}
+ protected void createSelectDataSetInheritance() throws Exception {
+ tEmbedRoot.insert(1, "root1", "e1-1", "e2-1", 0);
+ tEmbedRoot.insert(2, "root2", "e1-2", "e2-2", 1);
+ tEmbedChild.insert(2, "child-attr1");
+ }
+
protected void createUpdateDataSet() throws Exception {
tEmbedEntity1.insert(1, "n1", "e1", "e2", "e3", "e4");
}
@@ -298,4 +315,49 @@ public class EmbeddingIT extends ServerCase {
.select(context);
assertEquals(1, result.size());
}
+
+ @Test
+ public void testSelectWithInheritance() throws Exception {
+ createSelectDataSetInheritance();
+
+ List<EmbedRoot> roots = ObjectSelect.query(EmbedRoot.class)
+ .orderBy(EmbedRoot.NAME.asc())
+ .select(context);
+
+ assertEquals(2, roots.size());
+
+ EmbedRoot root = roots.get(0);
+ EmbedRoot child = roots.get(1);
+ assertTrue(child instanceof EmbedChild);
+
+ assertEquals("e1-1", root.getEmbedded().getEmbedded10());
+ assertEquals("e2-1", root.getEmbedded().getEmbedded20());
+
+ assertEquals("e1-2", child.getEmbedded().getEmbedded10());
+ assertEquals("e2-2", child.getEmbedded().getEmbedded20());
+ assertEquals("child-attr1", ((EmbedChild) child).getChildAttr());
+ }
+
+ @Test
+ public void testInsertWithInheritance() {
+ {
+ EmbedRoot root = context.newObject(EmbedRoot.class);
+ root.setName("root");
+ Embeddable1 embeddable1 = new Embeddable1();
+ embeddable1.setEmbedded10("root-10");
+ embeddable1.setEmbedded20("root-20");
+ root.setEmbedded(embeddable1);
+ }
+
+ {
+ EmbedChild child = context.newObject(EmbedChild.class);
+ child.setName("child");
+ Embeddable1 embeddable1 = new Embeddable1();
+ embeddable1.setEmbedded10("child-10");
+ embeddable1.setEmbedded20("child-20");
+ child.setEmbedded(embeddable1);
+ }
+
+ context.commitChanges();
+ }
}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedChild.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedChild.java
new file mode 100644
index 0000000..f90058f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedChild.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.embeddable;
+
+import org.apache.cayenne.testdo.embeddable.auto._EmbedChild;
+
+public class EmbedChild extends _EmbedChild {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedRoot.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedRoot.java
new file mode 100644
index 0000000..a7c5dd3
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/EmbedRoot.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.embeddable;
+
+import org.apache.cayenne.testdo.embeddable.auto._EmbedRoot;
+
+public class EmbedRoot extends _EmbedRoot {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedChild.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedChild.java
new file mode 100644
index 0000000..a43726a
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedChild.java
@@ -0,0 +1,87 @@
+package org.apache.cayenne.testdo.embeddable.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
+import org.apache.cayenne.testdo.embeddable.EmbedRoot;
+
+/**
+ * Class _EmbedChild 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 _EmbedChild extends EmbedRoot {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public static final StringProperty<String> CHILD_ATTR = PropertyFactory.createString("childAttr", String.class);
+
+ protected String childAttr;
+
+
+ public void setChildAttr(String childAttr) {
+ beforePropertyWrite("childAttr", this.childAttr, childAttr);
+ this.childAttr = childAttr;
+ }
+
+ public String getChildAttr() {
+ beforePropertyRead("childAttr");
+ return this.childAttr;
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "childAttr":
+ return this.childAttr;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "childAttr":
+ this.childAttr = (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.childAttr);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.childAttr = (String)in.readObject();
+ }
+
+}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java
index e5d29cb..82b8a1d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity1.java
@@ -21,7 +21,7 @@ import org.apache.cayenne.testdo.embeddable.Embeddable1;
*/
public abstract class _EmbedEntity1 extends BaseDataObject {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
public static final String ID_PK_COLUMN = "ID";
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java
index 5d867b2..c4875eb 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java
@@ -20,7 +20,7 @@ import org.apache.cayenne.testdo.embeddable.Embeddable1;
*/
public abstract class _EmbedEntity2 extends BaseDataObject {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
public static final String ID_PK_COLUMN = "ID";
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedRoot.java
similarity index 78%
copy from cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java
copy to cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedRoot.java
index 5d867b2..0d12bae 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedEntity2.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/embeddable/auto/_EmbedRoot.java
@@ -6,32 +6,31 @@ import java.io.ObjectOutputStream;
import org.apache.cayenne.BaseDataObject;
import org.apache.cayenne.exp.property.EmbeddableProperty;
-import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
import org.apache.cayenne.exp.property.PropertyFactory;
import org.apache.cayenne.exp.property.StringProperty;
-import org.apache.cayenne.testdo.embeddable.EmbedEntity1;
import org.apache.cayenne.testdo.embeddable.Embeddable1;
/**
- * Class _EmbedEntity2 was generated by Cayenne.
+ * Class _EmbedRoot 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 _EmbedEntity2 extends BaseDataObject {
+public abstract class _EmbedRoot extends BaseDataObject {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
public static final String ID_PK_COLUMN = "ID";
public static final EmbeddableProperty<Embeddable1> EMBEDDED = PropertyFactory.createEmbeddable("embedded", Embeddable1.class);
public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
- public static final EntityProperty<EmbedEntity1> ENTITY1 = PropertyFactory.createEntity("entity1", EmbedEntity1.class);
+ public static final NumericProperty<Integer> TYPE = PropertyFactory.createNumeric("type", Integer.class);
protected Embeddable1 embedded;
protected String name;
+ protected int type;
- protected Object entity1;
public void setEmbedded(Embeddable1 embedded) {
beforePropertyWrite("embedded", this.embedded, embedded);
@@ -53,12 +52,14 @@ public abstract class _EmbedEntity2 extends BaseDataObject {
return this.name;
}
- public void setEntity1(EmbedEntity1 entity1) {
- setToOneTarget("entity1", entity1, true);
+ public void setType(int type) {
+ beforePropertyWrite("type", this.type, type);
+ this.type = type;
}
- public EmbedEntity1 getEntity1() {
- return (EmbedEntity1)readProperty("entity1");
+ public int getType() {
+ beforePropertyRead("type");
+ return this.type;
}
@Override
@@ -72,8 +73,8 @@ public abstract class _EmbedEntity2 extends BaseDataObject {
return this.embedded;
case "name":
return this.name;
- case "entity1":
- return this.entity1;
+ case "type":
+ return this.type;
default:
return super.readPropertyDirectly(propName);
}
@@ -92,8 +93,8 @@ public abstract class _EmbedEntity2 extends BaseDataObject {
case "name":
this.name = (String)val;
break;
- case "entity1":
- this.entity1 = val;
+ case "type":
+ this.type = val == null ? 0 : (int)val;
break;
default:
super.writePropertyDirectly(propName, val);
@@ -113,7 +114,7 @@ public abstract class _EmbedEntity2 extends BaseDataObject {
super.writeState(out);
out.writeObject(this.embedded);
out.writeObject(this.name);
- out.writeObject(this.entity1);
+ out.writeInt(this.type);
}
@Override
@@ -121,7 +122,7 @@ public abstract class _EmbedEntity2 extends BaseDataObject {
super.readState(in);
this.embedded = (Embeddable1)in.readObject();
this.name = (String)in.readObject();
- this.entity1 = in.readObject();
+ this.type = in.readInt();
}
}
diff --git a/cayenne-server/src/test/resources/embeddable.map.xml b/cayenne-server/src/test/resources/embeddable.map.xml
index dbcae05..c01ed73 100644
--- a/cayenne-server/src/test/resources/embeddable.map.xml
+++ b/cayenne-server/src/test/resources/embeddable.map.xml
@@ -8,6 +8,10 @@
<embeddable-attribute name="embedded20" type="java.lang.String" db-attribute-name="EMBEDDED20"/>
<embeddable-attribute name="embedded10" type="java.lang.String" db-attribute-name="EMBEDDED10"/>
</embeddable>
+ <db-entity name="EMBED_CHILD">
+ <db-attribute name="CHILD_ATTR" type="VARCHAR" length="100"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
<db-entity name="EMBED_ENTITY1">
<db-attribute name="EMBEDDED10" type="VARCHAR" length="100"/>
<db-attribute name="EMBEDDED20" type="VARCHAR" length="100"/>
@@ -23,6 +27,17 @@
<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
<db-attribute name="NAME" type="VARCHAR" length="100"/>
</db-entity>
+ <db-entity name="EMBED_ROOT">
+ <db-attribute name="EMBEDDED10" type="VARCHAR" length="100"/>
+ <db-attribute name="EMBEDDED20" type="VARCHAR" length="100"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+ <db-attribute name="TYPE" type="INTEGER" isMandatory="true"/>
+ </db-entity>
+ <obj-entity name="EmbedChild" superEntityName="EmbedRoot" className="org.apache.cayenne.testdo.embeddable.EmbedChild">
+ <qualifier><![CDATA[type = 1]]></qualifier>
+ <obj-attribute name="childAttr" type="java.lang.String" db-attribute-path="child.CHILD_ATTR"/>
+ </obj-entity>
<obj-entity name="EmbedEntity1" className="org.apache.cayenne.testdo.embeddable.EmbedEntity1" dbEntityName="EMBED_ENTITY1">
<embedded-attribute name="embedded1" type="org.apache.cayenne.testdo.embeddable.Embeddable1"/>
<embedded-attribute name="embedded2" type="org.apache.cayenne.testdo.embeddable.Embeddable1">
@@ -35,12 +50,24 @@
<embedded-attribute name="embedded" type="org.apache.cayenne.testdo.embeddable.Embeddable1"/>
<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
</obj-entity>
+ <obj-entity name="EmbedRoot" className="org.apache.cayenne.testdo.embeddable.EmbedRoot" dbEntityName="EMBED_ROOT">
+ <qualifier><![CDATA[type = 0]]></qualifier>
+ <embedded-attribute name="embedded" type="org.apache.cayenne.testdo.embeddable.Embeddable1"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ <obj-attribute name="type" type="int" db-attribute-path="TYPE"/>
+ </obj-entity>
+ <db-relationship name="root" source="EMBED_CHILD" target="EMBED_ROOT">
+ <db-attribute-pair source="ID" target="ID"/>
+ </db-relationship>
<db-relationship name="untitledRel" source="EMBED_ENTITY1" target="EMBED_ENTITY2" toMany="true">
<db-attribute-pair source="ID" target="ENTITY1_ID"/>
</db-relationship>
<db-relationship name="untitledRel" source="EMBED_ENTITY2" target="EMBED_ENTITY1">
<db-attribute-pair source="ENTITY1_ID" target="ID"/>
</db-relationship>
+ <db-relationship name="child" source="EMBED_ROOT" target="EMBED_CHILD" toDependentPK="true">
+ <db-attribute-pair source="ID" target="ID"/>
+ </db-relationship>
<obj-relationship name="embedEntity2s" source="EmbedEntity1" target="EmbedEntity2" deleteRule="Deny" db-relationship-path="untitledRel"/>
<obj-relationship name="entity1" source="EmbedEntity2" target="EmbedEntity1" deleteRule="Nullify" db-relationship-path="untitledRel"/>
</data-map>