cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [1/3] cayenne git commit: CAY-2405 Broken prefetch of entity with inheritance and attribute with custom java type
Date Thu, 08 Feb 2018 13:01:56 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master 4a8a8425e -> 162d06e46


CAY-2405 Broken prefetch of entity with inheritance and attribute with custom java type


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

Branch: refs/heads/master
Commit: 7ae85329ca368523db1656e155f15094cbf87aa3
Parents: 4a8a842
Author: Nikita Timofeev <stariy95@gmail.com>
Authored: Thu Feb 8 14:39:48 2018 +0300
Committer: Nikita Timofeev <stariy95@gmail.com>
Committed: Thu Feb 8 14:39:48 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 .../select/DefaultSelectTranslator.java         |  59 +++++---
 .../query/QueryWithInheritancePrefetchIT.java   | 140 +++++++++++++++++++
 .../testdo/inheritance_with_enum/Dependent.java |   9 ++
 .../testdo/inheritance_with_enum/Root.java      |   9 ++
 .../testdo/inheritance_with_enum/Sub.java       |   9 ++
 .../testdo/inheritance_with_enum/Type.java      |  28 ++++
 .../inheritance_with_enum/auto/_Dependent.java  | 104 ++++++++++++++
 .../inheritance_with_enum/auto/_Root.java       | 131 +++++++++++++++++
 .../testdo/inheritance_with_enum/auto/_Sub.java |  87 ++++++++++++
 .../cayenne/unit/di/server/CayenneProjects.java |   1 +
 .../cayenne/unit/di/server/SchemaBuilder.java   |   3 +-
 .../resources/cayenne-inheritance-with-enum.xml |   7 +
 .../resources/inheritance-with-enum.map.xml     |  38 +++++
 14 files changed, 602 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 37878eb..bcbd440 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -36,6 +36,7 @@ CAY-2389 DbEntity qualifier with DbPath expression translates into wrong
SQL
 CAY-2392 Modeler: Unable to remove DataNode
 CAY-2397 Modeler: Unable to set enum:value as Entity qualifier
 CAY-2401 Modeler: NPE in ObjEntity sync action
+CAY-2405 Broken prefetch of entity with inheritance and attribute with custom java type
 
 ----------------------------------
 Release: 4.1.M1

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
index 67b3cfd..b1da173 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
@@ -687,8 +687,8 @@ public class DefaultSelectTranslator extends QueryAssembler implements
SelectTra
 
 				resetJoinStack();
 				DbRelationship r = null;
-				for (PathComponent<DbAttribute, DbRelationship> component : table.resolvePath(dbPrefetch,
-						getPathAliases())) {
+				for (PathComponent<DbAttribute, DbRelationship> component :
+						table.resolvePath(dbPrefetch, getPathAliases())) {
 					r = component.getRelationship();
 					dbRelationshipAdded(r, JoinType.LEFT_OUTER, null);
 				}
@@ -698,35 +698,48 @@ public class DefaultSelectTranslator extends QueryAssembler implements
SelectTra
 							, prefetch, oe.getName());
 				}
 
-				// add columns from the target entity, including those that are
-				// matched
-				// against the FK of the source entity. This is needed to
-				// determine
-				// whether optional relationships are null
+				// add columns from the target entity, including those that are matched
+				// against the FK of the source entity.
+				// This is needed to determine whether optional relationships are null
 
-				// go via target OE to make sure that Java types are mapped
-				// correctly...
+				// go via target OE to make sure that Java types are mapped correctly...
 				ObjRelationship targetRel = (ObjRelationship) prefetchExp.evaluate(oe);
 				ObjEntity targetEntity = targetRel.getTargetEntity();
 
 				String labelPrefix = dbPrefetch.getPath();
-				for (ObjAttribute oa : targetEntity.getAttributes()) {
-					Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
-					while (dbPathIterator.hasNext()) {
-						Object pathPart = dbPathIterator.next();
-
-						if (pathPart == null) {
-							throw new CayenneRuntimeException("ObjAttribute has no component: %s", oa.getName());
-						} else if (pathPart instanceof DbRelationship) {
-							DbRelationship rel = (DbRelationship) pathPart;
-							dbRelationshipAdded(rel, JoinType.INNER, null);
-						} else if (pathPart instanceof DbAttribute) {
-							DbAttribute attribute = (DbAttribute) pathPart;
 
-							appendColumn(columns, oa, attribute, attributes, labelPrefix + '.' + attribute.getName());
+				PropertyVisitor prefetchVisitor = new PropertyVisitor() {
+					public boolean visitAttribute(AttributeProperty property) {
+						ObjAttribute oa = property.getAttribute();
+						Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
+						while (dbPathIterator.hasNext()) {
+							Object pathPart = dbPathIterator.next();
+
+							if (pathPart == null) {
+								throw new CayenneRuntimeException("ObjAttribute has no component: %s", oa.getName());
+							} else if (pathPart instanceof DbRelationship) {
+								DbRelationship rel = (DbRelationship) pathPart;
+								dbRelationshipAdded(rel, JoinType.INNER, null);
+							} else if (pathPart instanceof DbAttribute) {
+								DbAttribute dbAttr = (DbAttribute) pathPart;
+
+								appendColumn(columns, oa, dbAttr, attributes, labelPrefix + '.' + dbAttr.getName());
+							}
 						}
+						return true;
 					}
-				}
+
+					public boolean visitToMany(ToManyProperty property) {
+						return true;
+					}
+
+					public boolean visitToOne(ToOneProperty property) {
+						return true;
+					}
+				};
+
+				ClassDescriptor prefetchClassDescriptor = entityResolver.getClassDescriptor(targetEntity.getName());
+				prefetchClassDescriptor.visitAllProperties(prefetchVisitor);
 
 				// append remaining target attributes such as keys
 				DbEntity targetDbEntity = r.getTargetEntity();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/query/QueryWithInheritancePrefetchIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/QueryWithInheritancePrefetchIT.java
b/cayenne-server/src/test/java/org/apache/cayenne/query/QueryWithInheritancePrefetchIT.java
new file mode 100644
index 0000000..75d5526
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/QueryWithInheritancePrefetchIT.java
@@ -0,0 +1,140 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.query;
+
+import java.util.List;
+
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.inheritance_with_enum.Dependent;
+import org.apache.cayenne.testdo.inheritance_with_enum.Root;
+import org.apache.cayenne.testdo.inheritance_with_enum.Sub;
+import org.apache.cayenne.testdo.inheritance_with_enum.Type;
+import org.apache.cayenne.unit.di.DataChannelInterceptor;
+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.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ * This one is about https://issues.apache.org/jira/browse/CAY-2405
+ *
+ * @since 4.1
+ */
+@UseServerRuntime(CayenneProjects.INHERITANCE_WITH_ENUM_PROJECT)
+public class QueryWithInheritancePrefetchIT extends ServerCase {
+
+    @Inject
+    private ServerRuntime runtime;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private DataChannelInterceptor queryInterceptor;
+
+    @Before
+    public void createTestData() throws Exception {
+        TableHelper tRoot = new TableHelper(dbHelper, "iwe_root");
+        tRoot.setColumns("id", "type", "name", "enum");
+
+        tRoot.insert(1, 0, "root1", null);
+        tRoot.insert(2, 1, "enum1", Type.type1.ordinal());
+        tRoot.insert(3, 1, "enum2", Type.type2.ordinal());
+
+        TableHelper tDependent = new TableHelper(dbHelper, "iwe_dependent");
+        tDependent.setColumns("id", "root_id", "name");
+
+        tDependent.insert(1, 1, "test1");
+        tDependent.insert(2, 2, "test2");
+        tDependent.insert(3, 3, "test3");
+    }
+
+    /**
+     * Validate that direct select of objects works
+     */
+    @Test
+    public void directQuery() {
+        List<Root> result = ObjectSelect.query(Root.class)
+                .orderBy("db:" + Root.ID_PK_COLUMN)
+                .select(runtime.newContext());
+
+        assertEquals(3, result.size());
+
+        assertNotNull(result.get(0));
+        assertFalse(result.get(0) instanceof Sub);
+        assertTrue(result.get(1) instanceof Sub);
+        assertTrue(result.get(2) instanceof Sub);
+
+        assertEquals(Type.type1, ((Sub)result.get(1)).getEnum());
+        assertEquals(Type.type2, ((Sub)result.get(2)).getEnum());
+    }
+
+    @Test
+    public void queryWithJointPrefetch() {
+        List<Dependent> result = ObjectSelect.query(Dependent.class)
+                .prefetch(Dependent.ROOT.joint())
+                .select(runtime.newContext());
+
+        assertPrefetchResult(result);
+    }
+
+    @Test
+    public void queryWithDisjointPrefetch() {
+        List<Dependent> result = ObjectSelect.query(Dependent.class)
+                .prefetch(Dependent.ROOT.disjoint())
+                .select(runtime.newContext());
+
+        assertPrefetchResult(result);
+    }
+
+    @Test
+    public void queryWithDisjointByIdPrefetch() {
+        List<Dependent> result = ObjectSelect.query(Dependent.class)
+                .prefetch(Dependent.ROOT.disjointById())
+                .select(runtime.newContext());
+
+        assertPrefetchResult(result);
+    }
+
+    private void assertPrefetchResult(final List<Dependent> result) {
+        assertEquals(3, result.size());
+
+        queryInterceptor.runWithQueriesBlocked(() -> {
+            assertNotNull(result.get(0).getRoot());
+            assertFalse(result.get(0).getRoot() instanceof Sub);
+            assertTrue(result.get(1).getRoot() instanceof Sub);
+            assertTrue(result.get(2).getRoot() instanceof Sub);
+
+            assertEquals(Type.type1, ((Sub) result.get(1).getRoot()).getEnum());
+            assertEquals(Type.type2, ((Sub) result.get(2).getRoot()).getEnum());
+        });
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Dependent.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Dependent.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Dependent.java
new file mode 100644
index 0000000..2b086dc
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Dependent.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.inheritance_with_enum;
+
+import org.apache.cayenne.testdo.inheritance_with_enum.auto._Dependent;
+
+public class Dependent extends _Dependent {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Root.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Root.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Root.java
new file mode 100644
index 0000000..423abb5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Root.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.inheritance_with_enum;
+
+import org.apache.cayenne.testdo.inheritance_with_enum.auto._Root;
+
+public class Root extends _Root {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Sub.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Sub.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Sub.java
new file mode 100644
index 0000000..28ddd46
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Sub.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.inheritance_with_enum;
+
+import org.apache.cayenne.testdo.inheritance_with_enum.auto._Sub;
+
+public class Sub extends _Sub {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Type.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Type.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Type.java
new file mode 100644
index 0000000..0a283c7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/Type.java
@@ -0,0 +1,28 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.testdo.inheritance_with_enum;
+
+/**
+ * @since 4.1
+ */
+public enum Type {
+    type1,
+    type2
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Dependent.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Dependent.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Dependent.java
new file mode 100644
index 0000000..e6aebf7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Dependent.java
@@ -0,0 +1,104 @@
+package org.apache.cayenne.testdo.inheritance_with_enum.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.inheritance_with_enum.Root;
+
+/**
+ * Class _Dependent 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 _Dependent extends BaseDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "id";
+
+    public static final Property<String> NAME = Property.create("name", String.class);
+    public static final Property<Root> ROOT = Property.create("root", Root.class);
+
+    protected String name;
+
+    protected Object root;
+
+    public void setName(String name) {
+        beforePropertyWrite("name", this.name, name);
+        this.name = name;
+    }
+
+    public String getName() {
+        beforePropertyRead("name");
+        return this.name;
+    }
+
+    public void setRoot(Root root) {
+        setToOneTarget("root", root, true);
+    }
+
+    public Root getRoot() {
+        return (Root)readProperty("root");
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "name":
+                return this.name;
+            case "root":
+                return this.root;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "name":
+                this.name = (String)val;
+                break;
+            case "root":
+                this.root = 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.name);
+        out.writeObject(this.root);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException
{
+        super.readState(in);
+        this.name = (String)in.readObject();
+        this.root = in.readObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Root.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Root.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Root.java
new file mode 100644
index 0000000..3a8a95f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Root.java
@@ -0,0 +1,131 @@
+package org.apache.cayenne.testdo.inheritance_with_enum.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.inheritance_with_enum.Dependent;
+
+/**
+ * Class _Root 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 _Root extends BaseDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "id";
+
+    public static final Property<String> NAME = Property.create("name", String.class);
+    public static final Property<Short> TYPE = Property.create("type", Short.class);
+    public static final Property<List<Dependent>> DEPENDENTS = Property.create("dependents",
List.class);
+
+    protected String name;
+    protected short type;
+
+    protected Object dependents;
+
+    public void setName(String name) {
+        beforePropertyWrite("name", this.name, name);
+        this.name = name;
+    }
+
+    public String getName() {
+        beforePropertyRead("name");
+        return this.name;
+    }
+
+    public void setType(short type) {
+        beforePropertyWrite("type", this.type, type);
+        this.type = type;
+    }
+
+    public short getType() {
+        beforePropertyRead("type");
+        return this.type;
+    }
+
+    public void addToDependents(Dependent obj) {
+        addToManyTarget("dependents", obj, true);
+    }
+
+    public void removeFromDependents(Dependent obj) {
+        removeToManyTarget("dependents", obj, true);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<Dependent> getDependents() {
+        return (List<Dependent>)readProperty("dependents");
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "name":
+                return this.name;
+            case "type":
+                return this.type;
+            case "dependents":
+                return this.dependents;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "name":
+                this.name = (String)val;
+                break;
+            case "type":
+                this.type = val == null ? 0 : (short)val;
+                break;
+            case "dependents":
+                this.dependents = 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.name);
+        out.writeShort(this.type);
+        out.writeObject(this.dependents);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException
{
+        super.readState(in);
+        this.name = (String)in.readObject();
+        this.type = in.readShort();
+        this.dependents = in.readObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Sub.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Sub.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Sub.java
new file mode 100644
index 0000000..9b8f8ef
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/inheritance_with_enum/auto/_Sub.java
@@ -0,0 +1,87 @@
+package org.apache.cayenne.testdo.inheritance_with_enum.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.inheritance_with_enum.Root;
+import org.apache.cayenne.testdo.inheritance_with_enum.Type;
+
+/**
+ * Class _Sub 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 _Sub extends Root {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "id";
+
+    public static final Property<Type> ENUM = Property.create("enum", Type.class);
+
+    protected Type _enum;
+
+
+    public void setEnum(Type _enum) {
+        beforePropertyWrite("enum", this._enum, _enum);
+        this._enum = _enum;
+    }
+
+    public Type getEnum() {
+        beforePropertyRead("enum");
+        return this._enum;
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "enum":
+                return this._enum;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "enum":
+                this._enum = (Type)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._enum);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException
{
+        super.readState(in);
+        this._enum = (Type)in.readObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/CayenneProjects.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/CayenneProjects.java
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/CayenneProjects.java
index 857027b..8d58595 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/CayenneProjects.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/CayenneProjects.java
@@ -82,4 +82,5 @@ public class CayenneProjects {
     public static final String WEIGHTED_SORT_PROJECT = "cayenne-weighted-sort.xml";
     public static final String HYBRID_DATA_OBJECT_PROJECT = "cayenne-hybrid-data-object.xml";
     public static final String JAVA8 = "cayenne-java8.xml";
+    public static final String INHERITANCE_WITH_ENUM_PROJECT = "cayenne-inheritance-with-enum.xml";
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
index aa1669c..ebd018d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
@@ -82,7 +82,8 @@ public class SchemaBuilder {
 			"table-primitives.map.xml", "generic.map.xml", "map-db1.map.xml", "map-db2.map.xml", "embeddable.map.xml",
 			"qualified.map.xml", "quoted-identifiers.map.xml", "inheritance-single-table1.map.xml",
 			"inheritance-vertical.map.xml", "oneway-rels.map.xml", "unsupported-distinct-types.map.xml",
-			"array-type.map.xml", "cay-2032.map.xml", "weighted-sort.map.xml", "hybrid-data-object.map.xml",
"java8.map.xml" };
+			"array-type.map.xml", "cay-2032.map.xml", "weighted-sort.map.xml", "hybrid-data-object.map.xml",
+			"java8.map.xml", "inheritance-with-enum.map.xml" };
 
 	// hardcoded dependent entities that should be excluded
 	// if LOBs are not supported

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/resources/cayenne-inheritance-with-enum.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cayenne-inheritance-with-enum.xml b/cayenne-server/src/test/resources/cayenne-inheritance-with-enum.xml
new file mode 100644
index 0000000..cd5e399
--- /dev/null
+++ b/cayenne-server/src/test/resources/cayenne-inheritance-with-enum.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd"
+	 project-version="10">
+	<map name="inheritance-with-enum"/>
+</domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7ae85329/cayenne-server/src/test/resources/inheritance-with-enum.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/inheritance-with-enum.map.xml b/cayenne-server/src/test/resources/inheritance-with-enum.map.xml
new file mode 100644
index 0000000..97027b2
--- /dev/null
+++ b/cayenne-server/src/test/resources/inheritance-with-enum.map.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+	 project-version="10">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.inheritance_with_enum"/>
+	<db-entity name="iwe_dependent">
+		<db-attribute name="id" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="name" type="VARCHAR" length="200"/>
+		<db-attribute name="root_id" type="INTEGER"/>
+	</db-entity>
+	<db-entity name="iwe_root">
+		<db-attribute name="enum" type="INTEGER"/>
+		<db-attribute name="id" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="name" type="VARCHAR" length="255"/>
+		<db-attribute name="type" type="SMALLINT" isMandatory="true"/>
+	</db-entity>
+	<obj-entity name="Dependent" className="org.apache.cayenne.testdo.inheritance_with_enum.Dependent"
dbEntityName="iwe_dependent">
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
+	</obj-entity>
+	<obj-entity name="Root" className="org.apache.cayenne.testdo.inheritance_with_enum.Root"
dbEntityName="iwe_root">
+		<qualifier><![CDATA[type = 0]]></qualifier>
+		<obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
+		<obj-attribute name="type" type="short" db-attribute-path="type"/>
+	</obj-entity>
+	<obj-entity name="Sub" superEntityName="Root" className="org.apache.cayenne.testdo.inheritance_with_enum.Sub">
+		<qualifier><![CDATA[type = 1]]></qualifier>
+		<obj-attribute name="enum" type="org.apache.cayenne.testdo.inheritance_with_enum.Type"
db-attribute-path="enum"/>
+	</obj-entity>
+	<db-relationship name="root" source="iwe_dependent" target="iwe_root">
+		<db-attribute-pair source="root_id" target="id"/>
+	</db-relationship>
+	<db-relationship name="dependents" source="iwe_root" target="iwe_dependent" toMany="true">
+		<db-attribute-pair source="id" target="root_id"/>
+	</db-relationship>
+	<obj-relationship name="root" source="Dependent" target="Root" deleteRule="Nullify" db-relationship-path="root"/>
+	<obj-relationship name="dependents" source="Root" target="Dependent" deleteRule="Deny"
db-relationship-path="dependents"/>
+</data-map>


Mime
View raw message