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 2014/12/18 12:13:47 UTC

[1/2] cayenne git commit: CAY-1979 | fix prefetches on Many-to-Many Relationships with Longvarchar

Repository: cayenne
Updated Branches:
  refs/heads/master 8eec5d4ed -> f8d9a780c


CAY-1979 | fix prefetches on Many-to-Many Relationships with Longvarchar


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

Branch: refs/heads/master
Commit: 49f4083ea14abdea268e983dc151436775962945
Parents: 8eec5d4
Author: Savva Kolbachev <s....@gmail.com>
Authored: Wed Dec 17 18:38:59 2014 +0300
Committer: Savva Kolbachev <s....@gmail.com>
Committed: Wed Dec 17 18:38:59 2014 +0300

----------------------------------------------------------------------
 .../translator/select/SelectTranslator.java     |  26 +--
 ...ectActionWithUnsupportedDistinctTypesIT.java | 161 +++++++++++++++++++
 .../unsupported_distinct_types/Customer.java    |   9 ++
 .../unsupported_distinct_types/Product.java     |   9 ++
 .../UnsupportedDistinctTypes.java               |  18 +++
 .../auto/_Customer.java                         |  48 ++++++
 .../auto/_Product.java                          |  79 +++++++++
 .../auto/_UnsupportedDistinctTypes.java         |  12 ++
 .../cayenne/unit/di/server/CayenneProjects.java |   1 +
 .../cayenne/unit/di/server/SchemaBuilder.java   |   2 +-
 .../cayenne-unsupported-distinct-types.xml      |   4 +
 .../unsupported-distinct-types.map.xml          |  57 +++++++
 12 files changed, 413 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
index ad171be..a2d16f1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
@@ -19,17 +19,6 @@
 
 package org.apache.cayenne.access.translator.select;
 
-import java.sql.Connection;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.jdbc.ColumnDescriptor;
@@ -60,6 +49,17 @@ import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.EqualsBuilder;
 import org.apache.cayenne.util.HashCodeBuilder;
 
+import java.sql.Connection;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * A builder of JDBC PreparedStatements based on Cayenne SelectQueries.
  * Translates SelectQuery to parameterized SQL string and wraps it in a
@@ -416,7 +416,9 @@ public class SelectTranslator extends QueryAssembler {
                         .resolvePath(pathExp, getPathAliases())) {
 
                     if (component.getRelationship() != null) {
-                        dbRelationshipAdded(component.getRelationship(), component.getJoinType(), null);
+                        // In this case we must have forcingDistinct = false (as default)
+                        // so we don't invoke dbRelationshipAdded() and invoke pushJoin() at once.
+                        getJoinStack().pushJoin(component.getRelationship(), component.getJoinType(), null);
                     }
 
                     lastComponent = component;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/SelectActionWithUnsupportedDistinctTypesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/SelectActionWithUnsupportedDistinctTypesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/SelectActionWithUnsupportedDistinctTypesIT.java
new file mode 100644
index 0000000..5a9fc2a
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/SelectActionWithUnsupportedDistinctTypesIT.java
@@ -0,0 +1,161 @@
+/*****************************************************************
+ *   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.access.jdbc;
+
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.unsupported_distinct_types.Customer;
+import org.apache.cayenne.testdo.unsupported_distinct_types.Product;
+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 java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@UseServerRuntime(CayenneProjects.UNSUPPORTED_DISTINCT_TYPES_PROJECT)
+public class SelectActionWithUnsupportedDistinctTypesIT extends ServerCase {
+
+    @Inject
+    protected DataContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    private TableHelper tProduct;
+    private TableHelper tComposition;
+    private TableHelper tCustomer;
+    private TableHelper tOrders;
+
+    @Before
+    public void setUp() throws Exception {
+        tProduct = new TableHelper(dbHelper, "PRODUCT");
+        tProduct.setColumns("ID", "LONGVARCHAR_COL").setColumnTypes(Types.INTEGER, Types.LONGNVARCHAR);
+
+        tCustomer = new TableHelper(dbHelper, "CUSTOMER").setColumnTypes(Types.INTEGER, Types.LONGNVARCHAR);
+        tCustomer.setColumns("ID", "LONGVARCHAR_COL");
+
+        tComposition = new TableHelper(dbHelper, "COMPOSITION");
+        tComposition.setColumns("BASE_ID", "CONTAINED_ID");
+
+        tOrders = new TableHelper(dbHelper, "ORDERS");
+        tOrders.setColumns("CUSTOMER_ID", "PRODUCT_ID");
+    }
+
+    private void createCompositionManyToManyDataSet() throws SQLException {
+        tProduct.insert(1, "product1");
+        tProduct.insert(2, "product2");
+        tProduct.insert(3, "product3");
+        tProduct.insert(4, "product4");
+
+        tComposition.insert(2, 1);
+        tComposition.insert(3, 1);
+        tComposition.insert(3, 2);
+        tComposition.insert(4, 1);
+        tComposition.insert(4, 2);
+        tComposition.insert(4, 3);
+    }
+
+    private void createOrdersManyToManyDataSet() throws SQLException {
+        tProduct.insert(1, "product1");
+        tProduct.insert(2, "product2");
+        tProduct.insert(3, "product3");
+
+        tCustomer.insert(1, "customer1");
+        tCustomer.insert(2, "customer2");
+        tCustomer.insert(3, "customer3");
+
+        tOrders.insert(1, 1);
+        tOrders.insert(2, 1);
+        tOrders.insert(2, 2);
+        tOrders.insert(3, 1);
+        tOrders.insert(3, 2);
+        tOrders.insert(3, 3);
+    }
+
+    @Test
+    public void testCompositionSelectManyToManyQuery() throws SQLException {
+        createCompositionManyToManyDataSet();
+
+        SelectQuery query = new SelectQuery(Product.class);
+        query.addPrefetch("contained");
+        query.addPrefetch("base");
+
+        List<Product> result = context.performQuery(query);
+        assertNotNull(result);
+
+        int i = 0;
+        for (Product product : result) {
+            List<Product> productsContained = product.getContained();
+            assertNotNull(productsContained);
+            assertEquals(i, productsContained.size());
+
+            List<Product> productsBase = product.getBase();
+            assertNotNull(productsBase);
+            assertEquals(3 - i, productsBase.size());
+
+            i++;
+        }
+    }
+
+    @Test
+    public void testOrdersSelectManyToManyQuery() throws SQLException {
+        createOrdersManyToManyDataSet();
+
+        SelectQuery productQuery = new SelectQuery(Product.class);
+        productQuery.addPrefetch("orderBy");
+
+        List<Product> productResult = context.performQuery(productQuery);
+        assertNotNull(productResult);
+
+        int i = 3;
+        for (Product product : productResult) {
+            List<Customer> orderBy = product.getOrderBy();
+            assertNotNull(orderBy);
+            assertEquals(i, orderBy.size());
+            i--;
+        }
+
+
+        SelectQuery customerQuery = new SelectQuery(Customer.class);
+        customerQuery.addPrefetch("order");
+
+        List<Customer> customerResult = context.performQuery(customerQuery);
+        assertNotNull(customerResult);
+
+        i = 1;
+        for (Customer customer : customerResult) {
+            List<Product> orders = customer.getOrder();
+            assertNotNull(orders);
+            assertEquals(i, orders.size());
+            i++;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/Customer.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/Customer.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/Customer.java
new file mode 100644
index 0000000..402cd73
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/Customer.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.unsupported_distinct_types;
+
+import org.apache.cayenne.testdo.unsupported_distinct_types.auto._Customer;
+
+public class Customer extends _Customer {
+
+    private static final long serialVersionUID = 1L; 
+
+}

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

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/UnsupportedDistinctTypes.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/UnsupportedDistinctTypes.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/UnsupportedDistinctTypes.java
new file mode 100644
index 0000000..cbe5986
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/UnsupportedDistinctTypes.java
@@ -0,0 +1,18 @@
+package org.apache.cayenne.testdo.unsupported_distinct_types;
+
+import org.apache.cayenne.testdo.unsupported_distinct_types.auto._UnsupportedDistinctTypes;
+
+public class UnsupportedDistinctTypes extends _UnsupportedDistinctTypes {
+
+    private static UnsupportedDistinctTypes instance;
+
+    private UnsupportedDistinctTypes() {}
+
+    public static UnsupportedDistinctTypes getInstance() {
+        if(instance == null) {
+            instance = new UnsupportedDistinctTypes();
+        }
+
+        return instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Customer.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Customer.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Customer.java
new file mode 100644
index 0000000..f071ed8
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Customer.java
@@ -0,0 +1,48 @@
+package org.apache.cayenne.testdo.unsupported_distinct_types.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.unsupported_distinct_types.Product;
+
+/**
+ * Class _Customer 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 _Customer extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    @Deprecated
+    public static final String LONGVARCHAR_COL_PROPERTY = "longvarcharCol";
+    @Deprecated
+    public static final String ORDER_PROPERTY = "order";
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<String> LONGVARCHAR_COL = new Property<String>("longvarcharCol");
+    public static final Property<List<Product>> ORDER = new Property<List<Product>>("order");
+
+    public void setLongvarcharCol(String longvarcharCol) {
+        writeProperty("longvarcharCol", longvarcharCol);
+    }
+    public String getLongvarcharCol() {
+        return (String)readProperty("longvarcharCol");
+    }
+
+    public void addToOrder(Product obj) {
+        addToManyTarget("order", obj, true);
+    }
+    public void removeFromOrder(Product obj) {
+        removeToManyTarget("order", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Product> getOrder() {
+        return (List<Product>)readProperty("order");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Product.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Product.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Product.java
new file mode 100644
index 0000000..02209b8
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_Product.java
@@ -0,0 +1,79 @@
+package org.apache.cayenne.testdo.unsupported_distinct_types.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.unsupported_distinct_types.Customer;
+import org.apache.cayenne.testdo.unsupported_distinct_types.Product;
+
+/**
+ * Class _Product 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 _Product extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    @Deprecated
+    public static final String LONGVARCHAR_COL_PROPERTY = "longvarcharCol";
+    @Deprecated
+    public static final String BASE_PROPERTY = "base";
+    @Deprecated
+    public static final String CONTAINED_PROPERTY = "contained";
+    @Deprecated
+    public static final String ORDER_BY_PROPERTY = "orderBy";
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<String> LONGVARCHAR_COL = new Property<String>("longvarcharCol");
+    public static final Property<List<Product>> BASE = new Property<List<Product>>("base");
+    public static final Property<List<Product>> CONTAINED = new Property<List<Product>>("contained");
+    public static final Property<List<Customer>> ORDER_BY = new Property<List<Customer>>("orderBy");
+
+    public void setLongvarcharCol(String longvarcharCol) {
+        writeProperty("longvarcharCol", longvarcharCol);
+    }
+    public String getLongvarcharCol() {
+        return (String)readProperty("longvarcharCol");
+    }
+
+    public void addToBase(Product obj) {
+        addToManyTarget("base", obj, true);
+    }
+    public void removeFromBase(Product obj) {
+        removeToManyTarget("base", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Product> getBase() {
+        return (List<Product>)readProperty("base");
+    }
+
+
+    public void addToContained(Product obj) {
+        addToManyTarget("contained", obj, true);
+    }
+    public void removeFromContained(Product obj) {
+        removeToManyTarget("contained", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Product> getContained() {
+        return (List<Product>)readProperty("contained");
+    }
+
+
+    public void addToOrderBy(Customer obj) {
+        addToManyTarget("orderBy", obj, true);
+    }
+    public void removeFromOrderBy(Customer obj) {
+        removeToManyTarget("orderBy", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Customer> getOrderBy() {
+        return (List<Customer>)readProperty("orderBy");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_UnsupportedDistinctTypes.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_UnsupportedDistinctTypes.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_UnsupportedDistinctTypes.java
new file mode 100644
index 0000000..37e81c7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/unsupported_distinct_types/auto/_UnsupportedDistinctTypes.java
@@ -0,0 +1,12 @@
+package org.apache.cayenne.testdo.unsupported_distinct_types.auto;
+
+
+
+/**
+ * This class 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 class _UnsupportedDistinctTypes {
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/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 5daa3a7..f731191 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
@@ -74,6 +74,7 @@ public class CayenneProjects {
     public static final String TESTMAP_PROJECT = "cayenne-testmap.xml";
     public static final String THINGS_PROJECT = "cayenne-things.xml";
     public static final String TOONE_PROJECT = "cayenne-toone.xml";
+    public static final String UNSUPPORTED_DISTINCT_TYPES_PROJECT = "cayenne-unsupported-distinct-types.xml";
     public static final String UUID_PROJECT = "cayenne-uuid.xml";
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/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 880f697..cd55c39 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
@@ -77,7 +77,7 @@ public class SchemaBuilder {
             "map-to-many.map.xml", "toone.map.xml", "meaningful-pk.map.xml", "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" };
+            "oneway-rels.map.xml", "unsupported-distinct-types.map.xml" };
 
     // hardcoded dependent entities that should be excluded
     // if LOBs are not supported

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/resources/cayenne-unsupported-distinct-types.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cayenne-unsupported-distinct-types.xml b/cayenne-server/src/test/resources/cayenne-unsupported-distinct-types.xml
new file mode 100644
index 0000000..9f0ab1d
--- /dev/null
+++ b/cayenne-server/src/test/resources/cayenne-unsupported-distinct-types.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain project-version="7">
+	<map name="unsupported-distinct-types"/>
+</domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/49f4083e/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml b/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
new file mode 100644
index 0000000..abf6fab
--- /dev/null
+++ b/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/7/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/7/modelMap http://cayenne.apache.org/schema/7/modelMap.xsd"
+	 project-version="7">
+	<property name="defaultPackage" value="org.apache.cayenne.testdo.unsupported_distinct_types"/>
+	<db-entity name="COMPOSITION">
+		<db-attribute name="BASE_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="CONTAINED_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="ORDERS">
+		<db-attribute name="CUSTOMER_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="PRODUCT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="CUSTOMER">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="LONGVARCHAR_COL" type="LONGVARCHAR"/>
+	</db-entity>
+	<db-entity name="PRODUCT">
+		<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="LONGVARCHAR_COL" type="LONGVARCHAR"/>
+	</db-entity>
+	<obj-entity name="Product" className="org.apache.cayenne.testdo.unsupported_distinct_types.Product" dbEntityName="PRODUCT">
+		<obj-attribute name="longvarcharCol" type="java.lang.String" db-attribute-path="LONGVARCHAR_COL"/>
+	</obj-entity>
+	<obj-entity name="Customer" className="org.apache.cayenne.testdo.unsupported_distinct_types.Customer" dbEntityName="CUSTOMER">
+		<obj-attribute name="longvarcharCol" type="java.lang.String" db-attribute-path="LONGVARCHAR_COL"/>
+	</obj-entity>
+	<db-relationship name="base" source="COMPOSITION" target="PRODUCT" toMany="false">
+		<db-attribute-pair source="BASE_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="contained" source="COMPOSITION" target="PRODUCT" toMany="false">
+		<db-attribute-pair source="CONTAINED_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="base" source="PRODUCT" target="COMPOSITION" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="BASE_ID"/>
+	</db-relationship>
+	<db-relationship name="contained" source="PRODUCT" target="COMPOSITION" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="CONTAINED_ID"/>
+	</db-relationship>
+	<db-relationship name="order" source="ORDERS" target="PRODUCT" toMany="false">
+		<db-attribute-pair source="PRODUCT_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="orderBy" source="ORDERS" target="CUSTOMER" toMany="false">
+		<db-attribute-pair source="CUSTOMER_ID" target="ID"/>
+	</db-relationship>
+	<db-relationship name="order" source="PRODUCT" target="ORDERS" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="PRODUCT_ID"/>
+	</db-relationship>
+	<db-relationship name="orderBy" source="CUSTOMER" target="ORDERS" toDependentPK="true" toMany="true">
+		<db-attribute-pair source="ID" target="CUSTOMER_ID"/>
+	</db-relationship>
+	<obj-relationship name="base" source="Product" target="Product" deleteRule="Deny" db-relationship-path="contained.base"/>
+	<obj-relationship name="contained" source="Product" target="Product" deleteRule="Deny" db-relationship-path="base.contained"/>
+	<obj-relationship name="orderBy" source="Product" target="Customer" deleteRule="Deny" db-relationship-path="order.orderBy"/>
+	<obj-relationship name="order" source="Customer" target="Product" deleteRule="Deny" db-relationship-path="orderBy.order"/>
+</data-map>


[2/2] cayenne git commit: CAY-1979 | fix prefetches on Many-to-Many Relationships with Longvarchar

Posted by aa...@apache.org.
CAY-1979 | fix prefetches on Many-to-Many Relationships with Longvarchar

clarifying commnet


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

Branch: refs/heads/master
Commit: f8d9a780cb4e777d70154a94142059bb8ef0feb0
Parents: 49f4083
Author: Savva Kolbachev <s....@gmail.com>
Authored: Wed Dec 17 18:38:59 2014 +0300
Committer: Andrus Adamchik <aa...@apache.org>
Committed: Thu Dec 18 14:13:10 2014 +0300

----------------------------------------------------------------------
 .../access/translator/select/SelectTranslator.java   | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/f8d9a780/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
index a2d16f1..b09fee4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslator.java
@@ -415,11 +415,16 @@ public class SelectTranslator extends QueryAssembler {
                 for (PathComponent<DbAttribute, DbRelationship> component : table
                         .resolvePath(pathExp, getPathAliases())) {
 
-                    if (component.getRelationship() != null) {
-                        // In this case we must have forcingDistinct = false (as default)
-                        // so we don't invoke dbRelationshipAdded() and invoke pushJoin() at once.
-                        getJoinStack().pushJoin(component.getRelationship(), component.getJoinType(), null);
-                    }
+					if (component.getRelationship() != null) {
+						// do not invoke dbRelationshipAdded(), invoke
+						// pushJoin() instead. This is to prevent
+						// 'forcingDistinct' flipping to true, that will result
+						// in unneeded extra processing and sometimes in invalid
+						// results (see CAY-1979). Distinctness of each row is
+						// guaranteed by the prefetch query semantics - we
+						// include target ID in the result columns
+						getJoinStack().pushJoin(component.getRelationship(), component.getJoinType(), null);
+					}
 
                     lastComponent = component;
                 }