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/11/02 08:10:27 UTC

[39/48] Installing Maven Failsafe Plugin

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsIT.java
new file mode 100644
index 0000000..52ee3af
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsIT.java
@@ -0,0 +1,476 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.EJBQLQuery;
+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.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.math.BigDecimal;
+import java.sql.Types;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextEJBQLConditionsIT extends ServerCase {
+
+    @Inject
+    protected ObjectContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    protected TableHelper tArtist;
+    protected TableHelper tPainting;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns(
+                "PAINTING_ID",
+                "ARTIST_ID",
+                "PAINTING_TITLE",
+                "ESTIMATED_PRICE").setColumnTypes(
+                Types.INTEGER,
+                Types.BIGINT,
+                Types.VARCHAR,
+                Types.DECIMAL);
+    }
+
+    protected void createCollectionDataSet() throws Exception {
+        tArtist.insert(33001, "B");
+        tArtist.insert(33002, "A");
+        tArtist.insert(33003, "D");
+
+        tPainting.insert(33009, 33001, "X", 5000);
+        tPainting.insert(33010, 33001, "Y", 5000);
+        tPainting.insert(33011, 33002, "Z", 5000);
+    }
+
+    protected void createLikeDataSet() throws Exception {
+        tPainting.insert(33001, null, "ABAAC", 3000);
+        tPainting.insert(33002, null, "ADDDD", 4000);
+        tPainting.insert(33003, null, "BDDDD", 5000);
+        tPainting.insert(33004, null, "BBDDDD", 5000);
+        tPainting.insert(33005, null, "_DDDD", 5000);
+    }
+
+    protected void createGreaterThanDataSet() throws Exception {
+        createLikeDataSet();
+    }
+
+    protected void createInDataSet() throws Exception {
+        tPainting.insert(33006, null, "A", 5000);
+        tPainting.insert(33007, null, "B", 5000);
+        tPainting.insert(33008, null, "C", 5000);
+    }
+
+    protected void createInSubqueryDataSet() throws Exception {
+        tPainting.insert(33012, null, "C", 5000);
+        tPainting.insert(33013, null, "D", 5000);
+        tPainting.insert(33014, null, "C", 5000);
+    }
+
+    public void testDateParameter() throws Exception {
+        createCollectionDataSet();
+
+        SelectQuery q = new SelectQuery(Artist.class);
+        List<Artist> allArtists = context.performQuery(q);
+
+        Date dob = new Date();
+        allArtists.get(0).setDateOfBirth(dob);
+        context.commitChanges();
+
+        String ejbql = "SELECT a FROM Artist a WHERE a.dateOfBirth = :x";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("x", dob);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        assertSame(allArtists.get(0), objects.get(0));
+    }
+
+    public void testArithmetics() throws Exception {
+        createLikeDataSet();
+
+        // TODO: andrus 02/25/2008 - fails on HSQLDB / succeeds on MySQL. HSQLDB error is
+        // "Unresolved parameter type : as both operands of aritmetic operator in
+
+        // statement"
+        // String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice < (1 + - 4.0 *
+        // - 1000.0)";
+        //
+        // EJBQLQuery query = new EJBQLQuery(ejbql);
+        // List<?> objects = createDataContext().performQuery(query);
+        // assertEquals(2, objects.size());
+        //
+        // Set<Object> ids = new HashSet<Object>();
+        // Iterator<?> it = objects.iterator();
+        // while (it.hasNext()) {
+        // Object id = Cayenne.pkForObject((Persistent) it.next());
+        // ids.add(id);
+        // }
+        //
+        // assertTrue(ids.contains(new Integer(33001)));
+        // assertTrue(ids.contains(new Integer(33002)));
+    }
+
+    public void testLike1() throws Exception {
+        createLikeDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE 'A%C'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33001)));
+    }
+
+    public void testNotLike() throws Exception {
+        createLikeDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle NOT LIKE 'A%C'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(4, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertFalse(ids.contains(new Integer(33001)));
+    }
+
+    public void testLike2() throws Exception {
+        createLikeDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE '_DDDD'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(3, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33002)));
+        assertTrue(ids.contains(new Integer(33003)));
+        assertTrue(ids.contains(new Integer(33005)));
+    }
+
+    public void testLikeEscape() throws Exception {
+        createLikeDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE 'X_DDDD' ESCAPE 'X'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33005)));
+    }
+
+    public void testLikeEscape_LikeParameter() throws Exception {
+        createLikeDataSet();
+
+        // test for CAY-1426
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE ?1 ESCAPE 'X'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter(1, "X_DDDD");
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33005)));
+    }
+
+    public void testLikeNullParameter() {
+        Artist a1 = context.newObject(Artist.class);
+        a1.setArtistName("a1");
+        a1.setDateOfBirth(null);
+        context.commitChanges();
+
+        EJBQLQuery eq1 = new EJBQLQuery(
+                "select a from Artist a where a.dateOfBirth like :param");
+        eq1.setParameter("param", null);
+        assertNotNull(Cayenne.objectForQuery(context, eq1));
+
+        EJBQLQuery eq2 = new EJBQLQuery(
+                "select a from Artist a where a.dateOfBirth like ?1");
+        eq2.setParameter(1, null);
+        assertNotNull(Cayenne.objectForQuery(context, eq2));
+    }
+
+    public void testIn() throws Exception {
+        createInDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle IN ('A', 'B')";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33006)));
+        assertTrue(ids.contains(new Integer(33007)));
+    }
+
+    public void testNotIn() throws Exception {
+        createInDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle NOT IN ('A', 'B')";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33008)));
+    }
+
+    public void testInSubquery() throws Exception {
+        createInSubqueryDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle IN ("
+                + "SELECT p1.paintingTitle FROM Painting p1 WHERE p1.paintingTitle = 'C'"
+                + ")";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33012)));
+        assertTrue(ids.contains(new Integer(33014)));
+    }
+
+    public void testCollectionEmpty() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS EMPTY";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Long(33003)));
+    }
+
+    public void testCollectionNotEmpty() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(33001l));
+        assertTrue(ids.contains(33002l));
+    }
+
+    public void testCollectionNotEmptyExplicitDistinct() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT DISTINCT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(33001l));
+        assertTrue(ids.contains(33002l));
+    }
+
+    public void testCollectionMemberOfParameter() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT a FROM Artist a WHERE :x MEMBER OF a.paintingArray";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("x", Cayenne.objectForPK(context, Painting.class, 33010));
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(33001l));
+    }
+
+    public void testGreaterOrEquals() throws Exception {
+        createGreaterThanDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice >= :estimatedPrice";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("estimatedPrice", new BigDecimal(4000));
+        List<?> objects = context.performQuery(query);
+        assertEquals(4, objects.size());
+    }
+
+    public void testLessOrEquals() throws Exception {
+        createGreaterThanDataSet();
+
+        String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice <= :estimatedPrice";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("estimatedPrice", new BigDecimal(4000));
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+    }
+
+    public void testCollectionNotMemberOfParameter() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT a FROM Artist a WHERE :x NOT MEMBER a.paintingArray";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("x", Cayenne.objectForPK(context, Painting.class, 33010));
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(33002l));
+        assertTrue(ids.contains(33003l));
+    }
+
+    public void testCollectionMemberOfThetaJoin() throws Exception {
+        createCollectionDataSet();
+
+        String ejbql = "SELECT p FROM Painting p, Artist a "
+                + "WHERE p MEMBER OF a.paintingArray AND a.artistName = 'B'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<Object> ids = new HashSet<Object>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = Cayenne.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33009)));
+        assertTrue(ids.contains(new Integer(33010)));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleIT.java
new file mode 100644
index 0000000..9a921f9
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleIT.java
@@ -0,0 +1,165 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.inherit.Address;
+import org.apache.cayenne.testdo.inherit.Department;
+import org.apache.cayenne.testdo.inherit.Manager;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+@UseServerRuntime(ServerCase.PEOPLE_PROJECT)
+public class DataContextEJBQLConditionsPeopleIT extends ServerCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private ObjectContext context;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+
+        TableHelper tPerson = new TableHelper(dbHelper, "PERSON");
+        tPerson.setColumns(
+                "PERSON_ID",
+                "NAME",
+                "PERSON_TYPE",
+                "SALARY",
+                "CLIENT_COMPANY_ID",
+                "DEPARTMENT_ID");
+
+        // manually break circular deps
+        tPerson.update().set("DEPARTMENT_ID", null, Types.INTEGER).execute();
+
+        dbHelper.deleteAll("ADDRESS");
+        dbHelper.deleteAll("DEPARTMENT");
+        dbHelper.deleteAll("PERSON_NOTES");
+        dbHelper.deleteAll("PERSON");
+        dbHelper.deleteAll("CLIENT_COMPANY");
+
+        // TODO: use TableHelper to create test data
+
+        Department d1 = context.newObject(Department.class);
+        d1.setName("d1");
+
+        Department d2 = context.newObject(Department.class);
+        d2.setName("d2");
+
+        Department d3 = context.newObject(Department.class);
+        d3.setName("d3");
+
+        context.commitChanges();
+
+        Manager m1 = context.newObject(Manager.class);
+        m1.setName("m1");
+        m1.setPersonType("EM");
+
+        Manager m2 = context.newObject(Manager.class);
+        m2.setName("m2");
+        m2.setPersonType("EM");
+
+        Manager m3 = context.newObject(Manager.class);
+        m3.setName("m3");
+        m3.setPersonType("EM");
+
+        Address a1 = context.newObject(Address.class);
+        m1.addToAddresses(a1);
+
+        Address a2 = context.newObject(Address.class);
+        m2.addToAddresses(a2);
+
+        Address a3 = context.newObject(Address.class);
+        m3.addToAddresses(a3);
+
+        d1.addToEmployees(m1);
+        d1.addToEmployees(m2);
+        d3.addToEmployees(m3);
+
+        context.commitChanges();
+
+        d1.setToManager(m1);
+        d2.setToManager(m2);
+        d3.setToManager(m3);
+
+        context.commitChanges();
+    }
+
+    public void testCollectionMemberOfId() throws Exception {
+
+        String ejbql = "SELECT DISTINCT m FROM Manager m JOIN m.managedDepartments d"
+                + " WHERE m MEMBER d.employees";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set<String> ids = new HashSet<String>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Manager m = (Manager) it.next();
+            ids.add(m.getName());
+        }
+
+        assertTrue(ids.contains("m1"));
+        assertTrue(ids.contains("m3"));
+    }
+
+    public void testCollectionNotMemberOfId() throws Exception {
+
+        String ejbql = "SELECT DISTINCT m FROM Manager m JOIN m.managedDepartments d"
+                + " WHERE m NOT MEMBER d.employees";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set<String> ids = new HashSet<String>();
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            Manager m = (Manager) it.next();
+            ids.add(m.getName());
+        }
+
+        assertTrue(ids.contains("m2"));
+    }
+
+    public void testCollectionNotMemberOfToOne() throws Exception {
+
+        // need a better test ... this query returns zero rows by definition
+        String ejbql = "SELECT a"
+                + " FROM Address a JOIN a.toEmployee m JOIN m.toDepartment d"
+                + " WHERE m NOT MEMBER d.employees";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List<?> objects = context.performQuery(query);
+        assertEquals(0, objects.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
deleted file mode 100644
index 628800b..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*****************************************************************
- *   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;
-
-import java.sql.Types;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.EJBQLQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.inherit.Address;
-import org.apache.cayenne.testdo.inherit.Department;
-import org.apache.cayenne.testdo.inherit.Manager;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.PEOPLE_PROJECT)
-public class DataContextEJBQLConditionsPeopleTest extends ServerCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private ObjectContext context;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-
-        TableHelper tPerson = new TableHelper(dbHelper, "PERSON");
-        tPerson.setColumns(
-                "PERSON_ID",
-                "NAME",
-                "PERSON_TYPE",
-                "SALARY",
-                "CLIENT_COMPANY_ID",
-                "DEPARTMENT_ID");
-
-        // manually break circular deps
-        tPerson.update().set("DEPARTMENT_ID", null, Types.INTEGER).execute();
-
-        dbHelper.deleteAll("ADDRESS");
-        dbHelper.deleteAll("DEPARTMENT");
-        dbHelper.deleteAll("PERSON_NOTES");
-        dbHelper.deleteAll("PERSON");
-        dbHelper.deleteAll("CLIENT_COMPANY");
-
-        // TODO: use TableHelper to create test data
-
-        Department d1 = context.newObject(Department.class);
-        d1.setName("d1");
-
-        Department d2 = context.newObject(Department.class);
-        d2.setName("d2");
-
-        Department d3 = context.newObject(Department.class);
-        d3.setName("d3");
-
-        context.commitChanges();
-
-        Manager m1 = context.newObject(Manager.class);
-        m1.setName("m1");
-        m1.setPersonType("EM");
-
-        Manager m2 = context.newObject(Manager.class);
-        m2.setName("m2");
-        m2.setPersonType("EM");
-
-        Manager m3 = context.newObject(Manager.class);
-        m3.setName("m3");
-        m3.setPersonType("EM");
-
-        Address a1 = context.newObject(Address.class);
-        m1.addToAddresses(a1);
-
-        Address a2 = context.newObject(Address.class);
-        m2.addToAddresses(a2);
-
-        Address a3 = context.newObject(Address.class);
-        m3.addToAddresses(a3);
-
-        d1.addToEmployees(m1);
-        d1.addToEmployees(m2);
-        d3.addToEmployees(m3);
-
-        context.commitChanges();
-
-        d1.setToManager(m1);
-        d2.setToManager(m2);
-        d3.setToManager(m3);
-
-        context.commitChanges();
-    }
-
-    public void testCollectionMemberOfId() throws Exception {
-
-        String ejbql = "SELECT DISTINCT m FROM Manager m JOIN m.managedDepartments d"
-                + " WHERE m MEMBER d.employees";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<String> ids = new HashSet<String>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Manager m = (Manager) it.next();
-            ids.add(m.getName());
-        }
-
-        assertTrue(ids.contains("m1"));
-        assertTrue(ids.contains("m3"));
-    }
-
-    public void testCollectionNotMemberOfId() throws Exception {
-
-        String ejbql = "SELECT DISTINCT m FROM Manager m JOIN m.managedDepartments d"
-                + " WHERE m NOT MEMBER d.employees";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<String> ids = new HashSet<String>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Manager m = (Manager) it.next();
-            ids.add(m.getName());
-        }
-
-        assertTrue(ids.contains("m2"));
-    }
-
-    public void testCollectionNotMemberOfToOne() throws Exception {
-
-        // need a better test ... this query returns zero rows by definition
-        String ejbql = "SELECT a"
-                + " FROM Address a JOIN a.toEmployee m JOIN m.toDepartment d"
-                + " WHERE m NOT MEMBER d.employees";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(0, objects.size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
deleted file mode 100644
index 2e3fd3c..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
+++ /dev/null
@@ -1,476 +0,0 @@
-/*****************************************************************
- *   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;
-
-import java.math.BigDecimal;
-import java.sql.Types;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.EJBQLQuery;
-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.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class DataContextEJBQLConditionsTest extends ServerCase {
-
-    @Inject
-    protected ObjectContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    protected TableHelper tArtist;
-    protected TableHelper tPainting;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-
-        tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
-        tPainting = new TableHelper(dbHelper, "PAINTING");
-        tPainting.setColumns(
-                "PAINTING_ID",
-                "ARTIST_ID",
-                "PAINTING_TITLE",
-                "ESTIMATED_PRICE").setColumnTypes(
-                Types.INTEGER,
-                Types.BIGINT,
-                Types.VARCHAR,
-                Types.DECIMAL);
-    }
-
-    protected void createCollectionDataSet() throws Exception {
-        tArtist.insert(33001, "B");
-        tArtist.insert(33002, "A");
-        tArtist.insert(33003, "D");
-
-        tPainting.insert(33009, 33001, "X", 5000);
-        tPainting.insert(33010, 33001, "Y", 5000);
-        tPainting.insert(33011, 33002, "Z", 5000);
-    }
-
-    protected void createLikeDataSet() throws Exception {
-        tPainting.insert(33001, null, "ABAAC", 3000);
-        tPainting.insert(33002, null, "ADDDD", 4000);
-        tPainting.insert(33003, null, "BDDDD", 5000);
-        tPainting.insert(33004, null, "BBDDDD", 5000);
-        tPainting.insert(33005, null, "_DDDD", 5000);
-    }
-
-    protected void createGreaterThanDataSet() throws Exception {
-        createLikeDataSet();
-    }
-
-    protected void createInDataSet() throws Exception {
-        tPainting.insert(33006, null, "A", 5000);
-        tPainting.insert(33007, null, "B", 5000);
-        tPainting.insert(33008, null, "C", 5000);
-    }
-
-    protected void createInSubqueryDataSet() throws Exception {
-        tPainting.insert(33012, null, "C", 5000);
-        tPainting.insert(33013, null, "D", 5000);
-        tPainting.insert(33014, null, "C", 5000);
-    }
-
-    public void testDateParameter() throws Exception {
-        createCollectionDataSet();
-
-        SelectQuery q = new SelectQuery(Artist.class);
-        List<Artist> allArtists = context.performQuery(q);
-
-        Date dob = new Date();
-        allArtists.get(0).setDateOfBirth(dob);
-        context.commitChanges();
-
-        String ejbql = "SELECT a FROM Artist a WHERE a.dateOfBirth = :x";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("x", dob);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        assertSame(allArtists.get(0), objects.get(0));
-    }
-
-    public void testArithmetics() throws Exception {
-        createLikeDataSet();
-
-        // TODO: andrus 02/25/2008 - fails on HSQLDB / succeeds on MySQL. HSQLDB error is
-        // "Unresolved parameter type : as both operands of aritmetic operator in
-
-        // statement"
-        // String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice < (1 + - 4.0 *
-        // - 1000.0)";
-        //
-        // EJBQLQuery query = new EJBQLQuery(ejbql);
-        // List<?> objects = createDataContext().performQuery(query);
-        // assertEquals(2, objects.size());
-        //
-        // Set<Object> ids = new HashSet<Object>();
-        // Iterator<?> it = objects.iterator();
-        // while (it.hasNext()) {
-        // Object id = Cayenne.pkForObject((Persistent) it.next());
-        // ids.add(id);
-        // }
-        //
-        // assertTrue(ids.contains(new Integer(33001)));
-        // assertTrue(ids.contains(new Integer(33002)));
-    }
-
-    public void testLike1() throws Exception {
-        createLikeDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE 'A%C'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33001)));
-    }
-
-    public void testNotLike() throws Exception {
-        createLikeDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle NOT LIKE 'A%C'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(4, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertFalse(ids.contains(new Integer(33001)));
-    }
-
-    public void testLike2() throws Exception {
-        createLikeDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE '_DDDD'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(3, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33002)));
-        assertTrue(ids.contains(new Integer(33003)));
-        assertTrue(ids.contains(new Integer(33005)));
-    }
-
-    public void testLikeEscape() throws Exception {
-        createLikeDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE 'X_DDDD' ESCAPE 'X'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33005)));
-    }
-
-    public void testLikeEscape_LikeParameter() throws Exception {
-        createLikeDataSet();
-
-        // test for CAY-1426
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle LIKE ?1 ESCAPE 'X'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter(1, "X_DDDD");
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33005)));
-    }
-
-    public void testLikeNullParameter() {
-        Artist a1 = context.newObject(Artist.class);
-        a1.setArtistName("a1");
-        a1.setDateOfBirth(null);
-        context.commitChanges();
-
-        EJBQLQuery eq1 = new EJBQLQuery(
-                "select a from Artist a where a.dateOfBirth like :param");
-        eq1.setParameter("param", null);
-        assertNotNull(Cayenne.objectForQuery(context, eq1));
-
-        EJBQLQuery eq2 = new EJBQLQuery(
-                "select a from Artist a where a.dateOfBirth like ?1");
-        eq2.setParameter(1, null);
-        assertNotNull(Cayenne.objectForQuery(context, eq2));
-    }
-
-    public void testIn() throws Exception {
-        createInDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle IN ('A', 'B')";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33006)));
-        assertTrue(ids.contains(new Integer(33007)));
-    }
-
-    public void testNotIn() throws Exception {
-        createInDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle NOT IN ('A', 'B')";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33008)));
-    }
-
-    public void testInSubquery() throws Exception {
-        createInSubqueryDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.paintingTitle IN ("
-                + "SELECT p1.paintingTitle FROM Painting p1 WHERE p1.paintingTitle = 'C'"
-                + ")";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33012)));
-        assertTrue(ids.contains(new Integer(33014)));
-    }
-
-    public void testCollectionEmpty() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS EMPTY";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Long(33003)));
-    }
-
-    public void testCollectionNotEmpty() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(33001l));
-        assertTrue(ids.contains(33002l));
-    }
-
-    public void testCollectionNotEmptyExplicitDistinct() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT DISTINCT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(33001l));
-        assertTrue(ids.contains(33002l));
-    }
-
-    public void testCollectionMemberOfParameter() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT a FROM Artist a WHERE :x MEMBER OF a.paintingArray";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("x", Cayenne.objectForPK(context, Painting.class, 33010));
-        List<?> objects = context.performQuery(query);
-        assertEquals(1, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(33001l));
-    }
-
-    public void testGreaterOrEquals() throws Exception {
-        createGreaterThanDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice >= :estimatedPrice";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("estimatedPrice", new BigDecimal(4000));
-        List<?> objects = context.performQuery(query);
-        assertEquals(4, objects.size());
-    }
-
-    public void testLessOrEquals() throws Exception {
-        createGreaterThanDataSet();
-
-        String ejbql = "SELECT p FROM Painting p WHERE p.estimatedPrice <= :estimatedPrice";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("estimatedPrice", new BigDecimal(4000));
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-    }
-
-    public void testCollectionNotMemberOfParameter() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT a FROM Artist a WHERE :x NOT MEMBER a.paintingArray";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("x", Cayenne.objectForPK(context, Painting.class, 33010));
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(33002l));
-        assertTrue(ids.contains(33003l));
-    }
-
-    public void testCollectionMemberOfThetaJoin() throws Exception {
-        createCollectionDataSet();
-
-        String ejbql = "SELECT p FROM Painting p, Artist a "
-                + "WHERE p MEMBER OF a.paintingArray AND a.artistName = 'B'";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        List<?> objects = context.performQuery(query);
-        assertEquals(2, objects.size());
-
-        Set<Object> ids = new HashSet<Object>();
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            Object id = Cayenne.pkForObject((Persistent) it.next());
-            ids.add(id);
-        }
-
-        assertTrue(ids.contains(new Integer(33009)));
-        assertTrue(ids.contains(new Integer(33010)));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteIT.java
new file mode 100644
index 0000000..728adaf
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteIT.java
@@ -0,0 +1,155 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextEJBQLDeleteIT extends ServerCase {
+
+    @Inject
+    protected ObjectContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    @Inject
+    protected ServerRuntime runtime;
+
+    protected TableHelper tPainting;
+
+    protected TableHelper tMeaningfulPKTest1Table;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+        dbHelper.deleteAll("MEANINGFUL_PK_DEP");
+        dbHelper.deleteAll("MEANINGFUL_PK_TEST1");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns(
+                "PAINTING_ID",
+                "ARTIST_ID",
+                "PAINTING_TITLE",
+                "ESTIMATED_PRICE").setColumnTypes(
+                Types.INTEGER,
+                Types.BIGINT,
+                Types.VARCHAR,
+                Types.DECIMAL);
+
+        tMeaningfulPKTest1Table = new TableHelper(dbHelper, "MEANINGFUL_PK_TEST1");
+        tMeaningfulPKTest1Table.setColumns("PK_ATTRIBUTE", "DESCR");
+    }
+
+    protected void createPaintingsDataSet() throws Exception {
+        tPainting.insert(33001, null, "P1", 3000);
+        tPainting.insert(33002, null, "P2", 5000);
+    }
+
+    protected void createMeaningfulPKDataSet() throws Exception {
+
+        for (int i = 1; i <= 33; i++) {
+            tMeaningfulPKTest1Table.insert(i, "a" + i);
+        }
+    }
+
+    public void testDeleteNoIdVar() throws Exception {
+        createPaintingsDataSet();
+
+        String ejbql = "delete from Painting";
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        QueryResponse result = context.performGenericQuery(query);
+
+        int[] count = result.firstUpdateCount();
+        assertNotNull(count);
+        assertEquals(1, count.length);
+        assertEquals(2, count[0]);
+    }
+
+    public void testDeleteNoQualifier() throws Exception {
+        createPaintingsDataSet();
+
+        String ejbql = "delete from Painting AS p";
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        QueryResponse result = context.performGenericQuery(query);
+
+        int[] count = result.firstUpdateCount();
+        assertNotNull(count);
+        assertEquals(1, count.length);
+        assertEquals(2, count[0]);
+    }
+
+    public void testDeleteSameEntityQualifier() throws Exception {
+        createPaintingsDataSet();
+
+        String ejbql = "delete from Painting AS p WHERE p.paintingTitle = 'P2'";
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        QueryResponse result = context.performGenericQuery(query);
+
+        int[] count = result.firstUpdateCount();
+        assertNotNull(count);
+        assertEquals(1, count.length);
+        assertEquals(1, count[0]);
+
+        ObjectContext freshContext = runtime.newContext();
+
+        assertNotNull(Cayenne.objectForPK(freshContext, Painting.class, 33001));
+        assertNull(Cayenne.objectForPK(freshContext, Painting.class, 33002));
+    }
+
+    public void testDeleteIdVar() throws Exception {
+
+        createMeaningfulPKDataSet();
+
+        EJBQLQuery q = new EJBQLQuery("select m.pkAttribute from MeaningfulPKTest1 m");
+
+        List<Integer> id = context.performQuery(q);
+
+        String ejbql = "delete from MeaningfulPKTest1 m WHERE m.pkAttribute in (:id)";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("id", id);
+        QueryResponse result = context.performGenericQuery(query);
+
+        int[] count = result.firstUpdateCount();
+        assertNotNull(count);
+        assertEquals(1, count.length);
+        assertEquals(33, count[0]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteTest.java
deleted file mode 100644
index ce95776..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDeleteTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*****************************************************************
- *   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;
-
-import java.sql.Types;
-import java.util.List;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.EJBQLQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class DataContextEJBQLDeleteTest extends ServerCase {
-
-    @Inject
-    protected ObjectContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    @Inject
-    protected ServerRuntime runtime;
-
-    protected TableHelper tPainting;
-
-    protected TableHelper tMeaningfulPKTest1Table;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-        dbHelper.deleteAll("MEANINGFUL_PK_DEP");
-        dbHelper.deleteAll("MEANINGFUL_PK_TEST1");
-
-        tPainting = new TableHelper(dbHelper, "PAINTING");
-        tPainting.setColumns(
-                "PAINTING_ID",
-                "ARTIST_ID",
-                "PAINTING_TITLE",
-                "ESTIMATED_PRICE").setColumnTypes(
-                Types.INTEGER,
-                Types.BIGINT,
-                Types.VARCHAR,
-                Types.DECIMAL);
-
-        tMeaningfulPKTest1Table = new TableHelper(dbHelper, "MEANINGFUL_PK_TEST1");
-        tMeaningfulPKTest1Table.setColumns("PK_ATTRIBUTE", "DESCR");
-    }
-
-    protected void createPaintingsDataSet() throws Exception {
-        tPainting.insert(33001, null, "P1", 3000);
-        tPainting.insert(33002, null, "P2", 5000);
-    }
-
-    protected void createMeaningfulPKDataSet() throws Exception {
-
-        for (int i = 1; i <= 33; i++) {
-            tMeaningfulPKTest1Table.insert(i, "a" + i);
-        }
-    }
-
-    public void testDeleteNoIdVar() throws Exception {
-        createPaintingsDataSet();
-
-        String ejbql = "delete from Painting";
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-
-        QueryResponse result = context.performGenericQuery(query);
-
-        int[] count = result.firstUpdateCount();
-        assertNotNull(count);
-        assertEquals(1, count.length);
-        assertEquals(2, count[0]);
-    }
-
-    public void testDeleteNoQualifier() throws Exception {
-        createPaintingsDataSet();
-
-        String ejbql = "delete from Painting AS p";
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-
-        QueryResponse result = context.performGenericQuery(query);
-
-        int[] count = result.firstUpdateCount();
-        assertNotNull(count);
-        assertEquals(1, count.length);
-        assertEquals(2, count[0]);
-    }
-
-    public void testDeleteSameEntityQualifier() throws Exception {
-        createPaintingsDataSet();
-
-        String ejbql = "delete from Painting AS p WHERE p.paintingTitle = 'P2'";
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-
-        QueryResponse result = context.performGenericQuery(query);
-
-        int[] count = result.firstUpdateCount();
-        assertNotNull(count);
-        assertEquals(1, count.length);
-        assertEquals(1, count[0]);
-
-        ObjectContext freshContext = runtime.newContext();
-
-        assertNotNull(Cayenne.objectForPK(freshContext, Painting.class, 33001));
-        assertNull(Cayenne.objectForPK(freshContext, Painting.class, 33002));
-    }
-
-    public void testDeleteIdVar() throws Exception {
-
-        createMeaningfulPKDataSet();
-
-        EJBQLQuery q = new EJBQLQuery("select m.pkAttribute from MeaningfulPKTest1 m");
-
-        List<Integer> id = context.performQuery(q);
-
-        String ejbql = "delete from MeaningfulPKTest1 m WHERE m.pkAttribute in (:id)";
-
-        EJBQLQuery query = new EJBQLQuery(ejbql);
-        query.setParameter("id", id);
-        QueryResponse result = context.performGenericQuery(query);
-
-        int[] count = result.firstUpdateCount();
-        assertNotNull(count);
-        assertEquals(1, count.length);
-        assertEquals(33, count[0]);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLFetchJoinIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLFetchJoinIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLFetchJoinIT.java
new file mode 100644
index 0000000..2a686d5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLFetchJoinIT.java
@@ -0,0 +1,417 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.ArtistExhibit;
+import org.apache.cayenne.testdo.testmap.Exhibit;
+import org.apache.cayenne.testdo.testmap.Gallery;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.DataChannelInterceptor;
+import org.apache.cayenne.unit.di.UnitTestClosure;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Date;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextEJBQLFetchJoinIT extends ServerCase {
+
+    @Inject
+    protected ObjectContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    @Inject
+    protected DataChannelInterceptor queryBlocker;
+
+    protected TableHelper tArtist;
+    protected TableHelper tPainting;
+    protected TableHelper tGallery;
+    protected TableHelper tExhibit;
+    protected TableHelper tArtistExhibit;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+        dbHelper.deleteAll("EXHIBIT");
+        dbHelper.deleteAll("GALLERY");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns(
+                "PAINTING_ID",
+                "ARTIST_ID",
+                "PAINTING_TITLE",
+                "ESTIMATED_PRICE").setColumnTypes(
+                Types.INTEGER,
+                Types.BIGINT,
+                Types.VARCHAR,
+                Types.DECIMAL);
+
+        tGallery = new TableHelper(dbHelper, "GALLERY");
+        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
+
+        tExhibit = new TableHelper(dbHelper, "EXHIBIT");
+        tExhibit.setColumns("EXHIBIT_ID", "GALLERY_ID", "CLOSING_DATE", "OPENING_DATE");
+
+        tArtistExhibit = new TableHelper(dbHelper, "ARTIST_EXHIBIT");
+        tArtistExhibit.setColumns("ARTIST_ID", "EXHIBIT_ID");
+    }
+
+    protected void createOneFetchJoinDataSet() throws Exception {
+        tArtist.insert(1, "A1");
+        tArtist.insert(2, "A2");
+        tArtist.insert(3, "A3");
+
+        tPainting.insert(1, 1, "P11", 3000d);
+        tPainting.insert(2, 2, "P2", 5000d);
+        tPainting.insert(3, 1, "P12", 3000d);
+    }
+
+    protected void createMultipleFetchJoinsDataSet() throws Exception {
+        createOneFetchJoinDataSet();
+
+        tGallery.insert(1, "gallery1");
+        tGallery.insert(2, "gallery2");
+
+        long t = System.currentTimeMillis();
+
+        tExhibit.insert(1, 1, new Date(1 + 10000), new Date(t + 20000));
+        tExhibit.insert(2, 1, new Date(1 + 30000), new Date(t + 40000));
+
+        tArtistExhibit.insert(1, 1);
+        tArtistExhibit.insert(1, 2);
+    }
+
+    public void testFetchJoinForOneEntity() throws Exception {
+        createOneFetchJoinDataSet();
+
+        String ejbql = "SELECT a FROM Artist a JOIN FETCH a.paintingArray ";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        final List<?> objects = context.performQuery(query);
+
+        queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertEquals(2, objects.size());
+
+                Iterator<?> it = objects.iterator();
+                while (it.hasNext()) {
+                    Artist a = (Artist) it.next();
+                    List<Painting> list = a.getPaintingArray();
+
+                    assertNotNull(list);
+                    assertFalse(((ValueHolder) list).isFault());
+
+                    for (Painting p : list) {
+                        assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                        // make sure properties are not null..
+                        assertNotNull(p.getPaintingTitle());
+                    }
+                }
+            }
+        });
+    }
+
+    public void testSeveralFetchJoins() throws Exception {
+        createMultipleFetchJoinsDataSet();
+
+        String ejbql = "SELECT a "
+                + "FROM Artist a JOIN FETCH a.paintingArray JOIN FETCH a.artistExhibitArray "
+                + "WHERE a.artistName = 'A1'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        final List<?> objects = context.performQuery(query);
+
+        queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertEquals(1, objects.size());
+
+                Artist a = (Artist) objects.get(0);
+                assertEquals("A1", a.getArtistName());
+
+                List<Painting> paintings = a.getPaintingArray();
+
+                assertNotNull(paintings);
+                assertFalse(((ValueHolder) paintings).isFault());
+                assertEquals(2, paintings.size());
+
+                List<String> expectedPaintingsNames = new ArrayList<String>();
+                expectedPaintingsNames.add("P11");
+                expectedPaintingsNames.add("P12");
+
+                Iterator<Painting> paintingsIterator = paintings.iterator();
+                while (paintingsIterator.hasNext()) {
+                    Painting p = paintingsIterator.next();
+                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    assertNotNull(p.getPaintingTitle());
+                    assertTrue(expectedPaintingsNames.contains(p.getPaintingTitle()));
+                }
+
+                List<ArtistExhibit> exibits = a.getArtistExhibitArray();
+
+                assertNotNull(exibits);
+                assertFalse(((ValueHolder) exibits).isFault());
+                assertEquals(2, exibits.size());
+
+                Iterator<ArtistExhibit> exibitsIterator = exibits.iterator();
+                while (exibitsIterator.hasNext()) {
+                    ArtistExhibit ae = exibitsIterator.next();
+                    assertEquals(PersistenceState.COMMITTED, ae.getPersistenceState());
+                    assertNotNull(ae.getObjectId());
+
+                }
+            }
+        });
+    }
+
+    public void testSeveralEntitiesFetchJoins() throws Exception {
+        createMultipleFetchJoinsDataSet();
+
+        String ejbql = "SELECT DISTINCT a , g "
+                + "FROM Artist a JOIN FETCH a.paintingArray , Gallery g JOIN FETCH g.exhibitArray "
+                + "WHERE a.artistName='A1' AND g.galleryName='gallery1'";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        final List<?> objects = context.performQuery(query);
+
+        queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertNotNull(objects);
+                assertFalse(objects.isEmpty());
+                assertEquals(1, objects.size());
+            }
+        });
+    }
+
+    public void testSeveralEntitiesAndScalarFetchInnerJoins() throws Exception {
+        createMultipleFetchJoinsDataSet();
+
+        String ejbql = "SELECT DISTINCT a, a.artistName , g "
+                + "FROM Artist a JOIN FETCH a.paintingArray, Gallery g JOIN FETCH g.exhibitArray "
+                + "ORDER BY a.artistName";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        final List<?> objects = context.performQuery(query);
+
+        queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertEquals(2, objects.size());
+
+                Object[] firstRow = (Object[]) objects.get(0);
+                Artist a = (Artist) firstRow[0];
+                assertEquals("A1", a.getArtistName());
+
+                List<Painting> paintings = a.getPaintingArray();
+
+                assertNotNull(paintings);
+                assertFalse(((ValueHolder) paintings).isFault());
+                assertEquals(2, paintings.size());
+
+                List<String> expectedPaintingsNames = new ArrayList<String>();
+                expectedPaintingsNames.add("P11");
+                expectedPaintingsNames.add("P12");
+
+                Iterator<Painting> paintingsIterator = paintings.iterator();
+                while (paintingsIterator.hasNext()) {
+                    Painting p = paintingsIterator.next();
+                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    assertNotNull(p.getPaintingTitle());
+                    assertTrue(expectedPaintingsNames.contains(p.getPaintingTitle()));
+                }
+                String artistName = (String) firstRow[1];
+                assertEquals("A1", artistName);
+
+                Gallery g1 = (Gallery) firstRow[2];
+                assertEquals("gallery1", g1.getGalleryName());
+
+                List<Exhibit> exibits = g1.getExhibitArray();
+
+                assertNotNull(exibits);
+                assertFalse(((ValueHolder) exibits).isFault());
+                assertEquals(2, exibits.size());
+
+                Object[] secondRow = (Object[]) objects.get(1);
+                a = (Artist) secondRow[0];
+                assertEquals("A2", a.getArtistName());
+
+                paintings = a.getPaintingArray();
+
+                assertNotNull(paintings);
+                assertFalse(((ValueHolder) paintings).isFault());
+                assertEquals(1, paintings.size());
+
+                expectedPaintingsNames = new ArrayList<String>();
+                expectedPaintingsNames.add("P2");
+
+                paintingsIterator = paintings.iterator();
+                while (paintingsIterator.hasNext()) {
+                    Painting p = paintingsIterator.next();
+                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    assertNotNull(p.getPaintingTitle());
+                    assertTrue(expectedPaintingsNames.contains(p.getPaintingTitle()));
+                }
+                artistName = (String) secondRow[1];
+                assertEquals("A2", artistName);
+
+                Gallery g2 = (Gallery) secondRow[2];
+                assertEquals(g1, g2);
+            }
+        });
+    }
+
+    public void testSeveralEntitiesAndScalarFetchOuterJoins() throws Exception {
+        createMultipleFetchJoinsDataSet();
+
+        String ejbql = "SELECT DISTINCT a, a.artistName , g "
+                + "FROM Artist a LEFT JOIN FETCH a.paintingArray, Gallery g LEFT JOIN FETCH g.exhibitArray "
+                + "ORDER BY a.artistName, g.galleryName";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+
+        final List<?> objects = context.performQuery(query);
+        queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertEquals(6, objects.size());
+
+                Object[] row = (Object[]) objects.get(0);
+                Artist a1 = (Artist) row[0];
+                assertEquals("A1", a1.getArtistName());
+
+                List<Painting> paintings = a1.getPaintingArray();
+
+                assertNotNull(paintings);
+                assertFalse(((ValueHolder) paintings).isFault());
+                assertEquals(2, paintings.size());
+
+                List<String> expectedPaintingsNames = new ArrayList<String>();
+                expectedPaintingsNames.add("P11");
+                expectedPaintingsNames.add("P12");
+
+                Iterator<Painting> paintingsIterator = paintings.iterator();
+                while (paintingsIterator.hasNext()) {
+                    Painting p = paintingsIterator.next();
+                    assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                    assertNotNull(p.getPaintingTitle());
+                    assertTrue(expectedPaintingsNames.contains(p.getPaintingTitle()));
+                }
+                String artistName1 = (String) row[1];
+                assertEquals("A1", artistName1);
+
+                Gallery g1 = (Gallery) row[2];
+                assertEquals("gallery1", g1.getGalleryName());
+
+                List<?> exibits = g1.getExhibitArray();
+
+                assertNotNull(exibits);
+                assertFalse(((ValueHolder) exibits).isFault());
+                assertEquals(2, exibits.size());
+
+                row = (Object[]) objects.get(1);
+
+                assertEquals(a1, row[0]);
+                assertEquals(artistName1, row[1]);
+
+                Gallery g2 = (Gallery) row[2];
+                assertEquals("gallery2", g2.getGalleryName());
+
+                exibits = g2.getExhibitArray();
+
+                assertTrue(exibits.isEmpty());
+
+                row = (Object[]) objects.get(2);
+
+                Artist a2 = (Artist) row[0];
+                assertEquals("A2", a2.getArtistName());
+
+                paintings = a2.getPaintingArray();
+
+                assertNotNull(paintings);
+                assertEquals(1, paintings.size());
+
+                Painting p = paintings.get(0);
+                assertEquals(PersistenceState.COMMITTED, p.getPersistenceState());
+                assertNotNull(p.getPaintingTitle());
+                assertEquals("P2", p.getPaintingTitle());
+
+                String artistName2 = (String) row[1];
+                assertEquals("A2", artistName2);
+                assertEquals(g1, row[2]);
+
+                row = (Object[]) objects.get(3);
+
+                assertEquals(a2, row[0]);
+                assertEquals(artistName2, row[1]);
+                assertEquals(g2, row[2]);
+
+                row = (Object[]) objects.get(4);
+
+                Artist a3 = (Artist) row[0];
+                assertEquals("A3", a3.getArtistName());
+
+                paintings = a3.getPaintingArray();
+
+                assertTrue(paintings.isEmpty());
+
+                String artistName3 = (String) row[1];
+                assertEquals("A3", artistName3);
+                assertEquals(g1, row[2]);
+
+                row = (Object[]) objects.get(5);
+
+                assertEquals(a3, row[0]);
+                assertEquals(artistName3, row[1]);
+                assertEquals(g2, row[2]);
+            }
+        });
+    }
+}