cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r564992 - in /cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src: main/java/org/apache/cayenne/access/jdbc/ test/java/org/apache/cayenne/access/
Date Sun, 12 Aug 2007 00:48:50 GMT
Author: aadamchik
Date: Sat Aug 11 17:48:49 2007
New Revision: 564992

URL: http://svn.apache.org/viewvc?view=rev&rev=564992
Log:
CAY-846 EJBQL Collections condition support

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
Sat Aug 11 17:48:49 2007
@@ -29,10 +29,20 @@
 import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
 import org.apache.cayenne.ejbql.EJBQLException;
 import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.ejbql.parser.EJBQLEquals;
+import org.apache.cayenne.ejbql.parser.EJBQLIdentificationVariable;
+import org.apache.cayenne.ejbql.parser.EJBQLPath;
 import org.apache.cayenne.ejbql.parser.EJBQLPositionalInputParameter;
 import org.apache.cayenne.ejbql.parser.EJBQLSubselect;
 import org.apache.cayenne.ejbql.parser.EJBQLTrimBoth;
 import org.apache.cayenne.ejbql.parser.EJBQLTrimSpecification;
+import org.apache.cayenne.ejbql.parser.Node;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
  * @since 3.0
@@ -107,28 +117,86 @@
     }
 
     public boolean visitMemberOf(EJBQLExpression expression) {
-        // handle as "? =|<> path" (an alt. way would've been a correlated subquery
-        // on the target entity)...
 
-        if (expression.isNegated()) {
-            context.switchToMarker(EJBQLSelectTranslator.makeDistinctMarker(), true);
-            context.append(" DISTINCT");
-            context.switchToMainBuffer();
+        // create a correlated subquery, using the following transformation:
 
-            visitNotEquals(expression, -1);
-            for (int i = 0; i < expression.getChildrenCount(); i++) {
-                expression.getChild(i).visit(this);
-                visitNotEquals(expression, i);
-            }
-        }
-        else {
-            visitEquals(expression, -1);
-            for (int i = 0; i < expression.getChildrenCount(); i++) {
-                expression.getChild(i).visit(this);
-                visitEquals(expression, i);
-            }
+        // * Subquery Root is always an entity that is a target of relationship
+        // * A subquery has a join based on reverse relationship, pointing to the
+        // original ID.
+        // * Join must be transled as a part of the subquery WHERE clause instead of
+        // FROM.
+        // * A condition is added: subquery_root_id = LHS_memberof
+
+        if (expression.getChildrenCount() != 2) {
+            throw new EJBQLException("MEMBER OF must have exactly two children, got: "
+                    + expression.getChildrenCount());
+        }
+
+        if (!(expression.getChild(1) instanceof EJBQLPath)) {
+            throw new EJBQLException(
+                    "Second child of the MEMBER OF must be a collection path, got: "
+                            + expression.getChild(1));
+        }
+
+        EJBQLPath path = (EJBQLPath) expression.getChild(1);
+
+        // make sure the ID for the path does not overlap with other condition
+        // joins...
+        String id = path.getAbsolutePath();
+
+        String correlatedEntityId = path.getId();
+        ClassDescriptor correlatedEntityDescriptor = context
+                .getEntityDescriptor(correlatedEntityId);
+        String correlatedTableName = correlatedEntityDescriptor
+                .getEntity()
+                .getDbEntity()
+                .getFullyQualifiedName();
+        String correlatedTableAlias = context.getTableAlias(
+                correlatedEntityId,
+                correlatedTableName);
+
+        String subqueryId = context.createIdAlias(id);
+        ClassDescriptor targetDescriptor = context.getEntityDescriptor(subqueryId);
+        String subqueryTableName = targetDescriptor
+                .getEntity()
+                .getDbEntity()
+                .getFullyQualifiedName();
+        String subqueryRootAlias = context.getTableAlias(subqueryId, subqueryTableName);
+
+        if (expression.isNegated()) {
+            context.append(" NOT");
         }
 
+        context.append(" EXISTS (SELECT 1 FROM ");
+        // not using "AS" to separate table name and alias name - OpenBase doesn't
+        // support "AS", and the rest of the databases do not care
+        context.append(subqueryTableName).append(' ').append(subqueryRootAlias);
+        context.append(" WHERE");
+
+        ObjRelationship relationship = context.getIncomingRelationship(id);
+        // TODO: andrus, 8/11/2007 flattened?
+        DbRelationship correlatedJoinRelationship = (DbRelationship) relationship
+                .getDbRelationships()
+                .get(0);
+        Iterator it = correlatedJoinRelationship.getJoins().iterator();
+        while (it.hasNext()) {
+            DbJoin join = (DbJoin) it.next();
+            context.append(' ').append(subqueryRootAlias).append('.').append(
+                    join.getTargetName()).append(" = ");
+            context.append(correlatedTableAlias).append('.').append(join.getSourceName());
+            context.append(" AND");
+        }
+
+        // translate subquery_root_id = LHS_of_memberof
+        EJBQLEquals equals = new EJBQLEquals(-1);
+        EJBQLIdentificationVariable identifier = new EJBQLIdentificationVariable(-1);
+        identifier.setText(subqueryId);
+        equals.jjtAddChild(identifier, 0);
+        equals.jjtAddChild((Node) expression.getChild(0), 1);
+        equals.visit(this);
+
+        context.append(")");
+
         return false;
     }
 
@@ -323,6 +391,32 @@
                 context.append(text);
             }
         }
+    }
+
+    public boolean visitIdentificationVariable(EJBQLExpression expression) {
+        // this is a match on a variable, like "x = :x"
+
+        ClassDescriptor descriptor = context.getEntityDescriptor(expression.getText());
+        if (descriptor == null) {
+            throw new EJBQLException("Invalid identification variable: "
+                    + expression.getText());
+        }
+
+        DbEntity table = descriptor.getEntity().getDbEntity();
+        String alias = context.getTableAlias(expression.getText(), table
+                .getFullyQualifiedName());
+
+        List pks = table.getPrimaryKey();
+
+        if (pks.size() == 1) {
+            DbAttribute pk = (DbAttribute) pks.get(0);
+            context.append(' ').append(alias).append('.').append(pk.getName());
+        }
+        else {
+            throw new EJBQLException(
+                    "Multi-column PK to-many matches are not yet supported.");
+        }
+        return false;
     }
 
     public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
Sat Aug 11 17:48:49 2007
@@ -96,9 +96,7 @@
 
         String rhsId = join.getRightHandSideId();
 
-        ObjRelationship joinRelationship = context
-                .getCompiledExpression()
-                .getIncomingRelationship(rhsId);
+        ObjRelationship joinRelationship = context.getIncomingRelationship(rhsId);
         if (joinRelationship == null) {
             throw new EJBQLException("No join configured for id " + rhsId);
         }
@@ -147,8 +145,7 @@
     }
 
     private String appendTable(String id) {
-        ClassDescriptor descriptor = context.getCompiledExpression().getEntityDescriptor(
-                id);
+        ClassDescriptor descriptor = context.getEntityDescriptor(id);
 
         String tableName = descriptor.getEntity().getDbEntity().getFullyQualifiedName();
         String alias = context.getTableAlias(id, tableName);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
Sat Aug 11 17:48:49 2007
@@ -58,8 +58,7 @@
         final String idVar = expression.getText();
 
         // append all table columns
-        ClassDescriptor descriptor = context.getCompiledExpression().getEntityDescriptor(
-                idVar);
+        ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
 
         PropertyVisitor visitor = new PropertyVisitor() {
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
Sat Aug 11 17:48:49 2007
@@ -82,8 +82,7 @@
     }
 
     public boolean visitIdentifier(EJBQLExpression expression) {
-        ClassDescriptor descriptor = context.getCompiledExpression().getEntityDescriptor(
-                expression.getText());
+        ClassDescriptor descriptor = context.getEntityDescriptor(expression.getText());
         if (descriptor == null) {
             throw new EJBQLException("Invalid identification variable: "
                     + expression.getText());
@@ -150,7 +149,7 @@
                 join.jjtAddChild(path, 0);
                 join.jjtAddChild(joinId, 1);
                 getJoinAppender().visitInnerJoin(join);
-                
+
                 this.lastAlias = context.getTableAlias(fullPath, currentEntity
                         .getDbEntityName());
             }
@@ -159,10 +158,11 @@
                 join.jjtAddChild(path, 0);
                 join.jjtAddChild(joinId, 1);
                 getJoinAppender().visitOuterJoin(join);
-                
-                Relationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
+
+                Relationship lastRelationship = currentEntity
+                        .getRelationship(lastPathComponent);
                 ObjEntity targetEntity = (ObjEntity) lastRelationship.getTargetEntity();
-                
+
                 this.lastAlias = context.getTableAlias(fullPath, targetEntity
                         .getDbEntityName());
             }
@@ -239,11 +239,7 @@
 
             if (pks.size() == 1) {
                 DbAttribute pk = (DbAttribute) pks.get(0);
-                context
-                        .append(' ')
-                        .append(alias)
-                        .append('.')
-                        .append(pk.getName());
+                context.append(' ').append(alias).append('.').append(pk.getName());
             }
             else {
                 throw new EJBQLException(

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
Sat Aug 11 17:48:49 2007
@@ -23,8 +23,10 @@
 
 import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
 import org.apache.cayenne.ejbql.EJBQLException;
+import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.query.SQLResultSetMapping;
 import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
  * A context used for translating of EJBQL to SQL.
@@ -42,6 +44,7 @@
     private Map attributes;
     private Map reusableJoins;
     private Map parameters;
+    private Map idAliases;
     private int columnAliasPosition;
 
     // a flag indicating whether column expressions should be treated as result columns or
@@ -62,6 +65,57 @@
                 .getObjectClass(), sql);
         query.setParameters(boundParameters);
         return query;
+    }
+
+    private String resolveId(String id) {
+        if (idAliases == null) {
+            return id;
+        }
+
+        String resolvedAlias = (String) idAliases.get(id);
+        if (resolvedAlias != null) {
+            return resolvedAlias;
+        }
+
+        return id;
+    }
+
+    /**
+     * Looks up entity descriptor for an identifier that can be a compiled expression id
+     * or one of the aliases.
+     */
+    ClassDescriptor getEntityDescriptor(String id) {
+        return compiledExpression.getEntityDescriptor(resolveId(id));
+    }
+
+    ObjRelationship getIncomingRelationship(String id) {
+        return compiledExpression.getIncomingRelationship(resolveId(id));
+    }
+
+    /**
+     * Creates a previously unused id alias for an entity identified by an id.
+     */
+    String createIdAlias(String id) {
+
+        if (idAliases == null) {
+            idAliases = new HashMap();
+        }
+
+        for (int i = 0; i < 1000; i++) {
+            String alias = id + "_alias" + i;
+            if (idAliases.containsKey(alias)) {
+                continue;
+            }
+
+            if (compiledExpression.getEntityDescriptor(alias) != null) {
+                continue;
+            }
+
+            idAliases.put(alias, id);
+            return alias;
+        }
+
+        throw new EJBQLException("Failed to create id alias");
     }
 
     /**

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java?view=auto&rev=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsPeopleTest.java
Sat Aug 11 17:48:49 2007
@@ -0,0 +1,140 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+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.query.EJBQLQuery;
+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.PeopleCase;
+
+public class DataContextEJBQLConditionsPeopleTest extends PeopleCase {
+
+    protected void setUp() throws Exception {
+        deleteTestData();
+
+        ObjectContext context = createDataContext();
+        Department d1 = (Department) context.newObject(Department.class);
+        d1.setName("d1");
+
+        Department d2 = (Department) context.newObject(Department.class);
+        d2.setName("d2");
+
+        Department d3 = (Department) context.newObject(Department.class);
+        d3.setName("d3");
+
+        context.commitChanges();
+
+        Manager m1 = (Manager) context.newObject(Manager.class);
+        m1.setName("m1");
+        m1.setPersonType("EM");
+
+        Manager m2 = (Manager) context.newObject(Manager.class);
+        m2.setName("m2");
+        m2.setPersonType("EM");
+
+        Manager m3 = (Manager) context.newObject(Manager.class);
+        m3.setName("m3");
+        m3.setPersonType("EM");
+
+        Address a1 = (Address) context.newObject(Address.class);
+        m1.addToAddresses(a1);
+
+        Address a2 = (Address) context.newObject(Address.class);
+        m2.addToAddresses(a2);
+
+        Address a3 = (Address) 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";
+
+        ObjectContext context = createDataContext();
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set ids = new HashSet();
+        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";
+
+        ObjectContext context = createDataContext();
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+
+        Set ids = new HashSet();
+        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";
+
+        ObjectContext context = createDataContext();
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List objects = context.performQuery(query);
+        assertEquals(0, objects.size());
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java?view=diff&rev=564992&r1=564991&r2=564992
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
Sat Aug 11 17:48:49 2007
@@ -237,7 +237,7 @@
     public void testCollectionMemberOfParameter() throws Exception {
         createTestData("prepareCollection");
 
-        String ejbql = "SELECT a FROM Artist a " + "WHERE :x MEMBER OF a.paintingArray";
+        String ejbql = "SELECT a FROM Artist a WHERE :x MEMBER OF a.paintingArray";
 
         ObjectContext context = createDataContext();
 
@@ -259,50 +259,50 @@
         assertTrue(ids.contains(new Integer(33001)));
     }
     
-//    public void testCollectionNotMemberOfParameter() throws Exception {
-//        createTestData("prepareCollection");
-//
-//        String ejbql = "SELECT a FROM Artist a " + "WHERE :x NOT MEMBER a.paintingArray";
-//
-//        ObjectContext context = createDataContext();
-//
-//        EJBQLQuery query = new EJBQLQuery(ejbql);
-//        query.setParameter("x", DataObjectUtils.objectForPK(
-//                context,
-//                Painting.class,
-//                33010));
-//        List objects = context.performQuery(query);
-//        assertEquals(2, objects.size());
-//
-//        Set ids = new HashSet();
-//        Iterator it = objects.iterator();
-//        while (it.hasNext()) {
-//            Object id = DataObjectUtils.pkForObject((Persistent) it.next());
-//            ids.add(id);
-//        }
-//        
-//        assertTrue(ids.contains(new Integer(33002)));
-//        assertTrue(ids.contains(new Integer(33003)));
-//    }
-
-//    public void testCollectionMemberOfThetaJoin() throws Exception {
-//        createTestData("prepareCollection");
-//
-//        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 = createDataContext().performQuery(query);
-//        assertEquals(2, objects.size());
-//
-//        Set ids = new HashSet();
-//        Iterator it = objects.iterator();
-//        while (it.hasNext()) {
-//            Object id = DataObjectUtils.pkForObject((Persistent) it.next());
-//            ids.add(id);
-//        }
-//
-//        assertTrue(ids.contains(new Integer(33009)));
-//        assertTrue(ids.contains(new Integer(33010)));
-//    }
+    public void testCollectionNotMemberOfParameter() throws Exception {
+        createTestData("prepareCollection");
+
+        String ejbql = "SELECT a FROM Artist a WHERE :x NOT MEMBER a.paintingArray";
+
+        ObjectContext context = createDataContext();
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        query.setParameter("x", DataObjectUtils.objectForPK(
+                context,
+                Painting.class,
+                33010));
+        List objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set ids = new HashSet();
+        Iterator it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = DataObjectUtils.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+        
+        assertTrue(ids.contains(new Integer(33002)));
+        assertTrue(ids.contains(new Integer(33003)));
+    }
+
+    public void testCollectionMemberOfThetaJoin() throws Exception {
+        createTestData("prepareCollection");
+
+        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 = createDataContext().performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set ids = new HashSet();
+        Iterator it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = DataObjectUtils.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33009)));
+        assertTrue(ids.contains(new Integer(33010)));
+    }
 }



Mime
View raw message