You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/05/18 17:56:36 UTC

svn commit: r775997 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/crite...

Author: faywang
Date: Mon May 18 15:56:35 2009
New Revision: 775997

URL: http://svn.apache.org/viewvc?rev=775997&view=rev
Log:
OPENJPA-1013: parameter support for Criteria Query

Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java Mon May 18 15:56:35 2009
@@ -55,17 +55,17 @@
     protected static final int EX_UNSUPPORTED = 2;
 
     // common implicit type settings
-    protected static final Class<Object> TYPE_OBJECT = Object.class;
-    protected static final Class<String> TYPE_STRING = String.class;
-    protected static final Class<Character> TYPE_CHAR_OBJ = Character.class;
-    protected static final Class<Number> TYPE_NUMBER = Number.class;
-    protected static final Class<Collection> TYPE_COLLECTION = Collection.class;
-    protected static final Class<Map> TYPE_MAP = Map.class;
+    public static final Class<Object> TYPE_OBJECT = Object.class;
+    public static final Class<String> TYPE_STRING = String.class;
+    public static final Class<Character> TYPE_CHAR_OBJ = Character.class;
+    public static final Class<Number> TYPE_NUMBER = Number.class;
+    public static final Class<Collection> TYPE_COLLECTION = Collection.class;
+    public static final Class<Map> TYPE_MAP = Map.class;
 
     // contains types for setImplicitTypes
-    protected static final int CONTAINS_TYPE_ELEMENT = 1;
-    protected static final int CONTAINS_TYPE_KEY = 2;
-    protected static final int CONTAINS_TYPE_VALUE = 3;
+    public static final int CONTAINS_TYPE_ELEMENT = 1;
+    public static final int CONTAINS_TYPE_KEY = 2;
+    public static final int CONTAINS_TYPE_VALUE = 3;
 
     private static final Localizer _loc = Localizer.forPackage
         (AbstractExpressionBuilder.class);
@@ -366,7 +366,7 @@
     /**
      * Perform conversions to make values compatible.
      */
-    private void convertTypes(Value val1, Value val2) {
+    public static void convertTypes(Value val1, Value val2) {
         Class<?> t1 = val1.getType();
         Class<?> t2 = val2.getType();
 
@@ -415,7 +415,7 @@
     /**
      * Perform conversions to make values compatible.
      */
-    private void convertTypesQuotedNumbers(Value val1, Value val2) {
+    public static void convertTypesQuotedNumbers(Value val1, Value val2) {
         Class<?> t1 = val1.getType();
         Class<?> t2 = val2.getType();
 
@@ -457,7 +457,7 @@
     /**
      * Return true if given class can be used as a number.
      */
-    private static boolean isNumeric(Class<?> type) {
+    public static boolean isNumeric(Class<?> type) {
         type = Filters.wrap(type);
         return Number.class.isAssignableFrom(type)
             || type == Character.TYPE || type == TYPE_CHAR_OBJ;

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java Mon May 18 15:56:35 2009
@@ -413,33 +413,32 @@
         assertEquivalence(q, jpql);
     }
     
-    @AllowFailure
     public void testParameters1() {
         String jpql = "SELECT c FROM Customer c Where c.status = :stat";
         CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
-        Parameter<Integer> param = cb.parameter(Integer.class);
+        Parameter<Integer> param = cb.parameter(Integer.class, "stat");
         q.select(c).where(cb.equal(c.get(Customer_.status), param));
         
         assertEquivalence(q, jpql, new String[]{"stat"}, new Object[] {1});
     }
 
-    @AllowFailure
     public void testParameters2() {
-        String jpql = "SELECT c FROM Customer c Where c.status = :stat AND c.name = :name";
+        String jpql = "SELECT c FROM Customer c Where c.status = :stat AND " + 
+            "c.name = :name";
         CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
         Parameter<Integer> param1 = cb.parameter(Integer.class, "stat");
         Parameter<String> param2 = cb.parameter(String.class, "name");
-        q.select(c).where(cb.equal(c.get(Customer_.status), param1),
-            cb.equal(c.get(Customer_.name), param2));
+        q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
+            cb.equal(c.get(Customer_.name), param2)));
 
-        assertEquivalence(q, jpql, new String[] { "stat", "name" }, new Object[] { 1, "test" });
+        assertEquivalence(q, jpql, new String[] { "stat", "name" }, 
+            new Object[] { 1, "test" });
     }
 
-    @AllowFailure
     public void testParameters3() {
-        String jpql = "SELECT c FROM Customer c Where c.status = :1";
+        String jpql = "SELECT c FROM Customer c Where c.status = ?1";
         CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
         Parameter<Integer> param = cb.parameter(Integer.class);
@@ -447,31 +446,31 @@
         assertEquivalence(q, jpql, new Object[] { 1 });
     }
 
-    @AllowFailure
     public void testParameters4() {
-        String jpql = "SELECT c FROM Customer c Where c.status = :1 AND c.name = :2";
+        String jpql = "SELECT c FROM Customer c Where c.status = ?1 AND " + 
+            "c.name = ?2";
         CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
         Parameter<Integer> param1 = cb.parameter(Integer.class);
         Parameter<Integer> param2 = cb.parameter(Integer.class);
-        q.select(c).where(cb.equal(c.get(Customer_.status), param1),
-            cb.equal(c.get(Customer_.name), param2));    
+        q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
+            cb.equal(c.get(Customer_.name), param2)));    
         assertEquivalence(q, jpql, new Object[] { 1, "test" });
     }
     
-    // collection-valued input parameter
+    // do not support collection-valued input parameter
     @AllowFailure
     public void testParameters5() {
         String jpql = "SELECT c FROM Customer c Where c.status IN (:coll)";
         CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
         Parameter<List> param1 = cb.parameter(List.class);
-        q.select(c).where(cb.equal(c.get(Customer_.status), param1));    
+        //q.select(c).where(cb.in(c.get(Customer_.status)).value(params1));    
         List vals = new ArrayList();
         vals.add(1);
         vals.add(2);
         
-        assertEquivalence(q, jpql,  new String[] {"coll"}, new Object[] {vals});
+        //assertEquivalence(q, jpql,  new String[] {"coll"}, new Object[] {vals});
     }
     
     @AllowFailure

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java Mon May 18 15:56:35 2009
@@ -34,10 +34,14 @@
 import javax.persistence.criteria.Subquery;
 import javax.persistence.metamodel.Entity;
 
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
+import org.apache.openjpa.kernel.exps.Path;
 import org.apache.openjpa.kernel.exps.QueryExpressions;
 import org.apache.openjpa.kernel.exps.Value;
 import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.persistence.meta.MetamodelImpl;
 import org.apache.openjpa.persistence.meta.Types;
 
@@ -57,6 +61,7 @@
     private List<Expression<?>> _groups;
     private PredicateImpl       _having;
     private Boolean             _distinct;
+    private LinkedMap           _parameterTypes;
     
     public CriteriaQueryImpl(MetamodelImpl model) {
         this._model = model;
@@ -164,6 +169,14 @@
         return null;
     }
     
+    public LinkedMap getParameterTypes() {
+        return _parameterTypes;
+    }
+    
+    public void setParameterTypes(LinkedMap parameterTypes) {
+        _parameterTypes = parameterTypes;
+    }
+    
     /**
      * Populate kernel expressions.
      */
@@ -184,11 +197,11 @@
     //    exps.fetchInnerPaths = null; // String[]
 	//    exps.fetchPaths = null;      // String[]
 	    exps.filter = _where == null ? factory.emptyExpression() 
-	    		: _where.toKernelExpression(factory, _model);
+	    		: _where.toKernelExpression(factory, _model, this);
 	    
 	    evalGrouping(exps, factory);
 	    exps.having = _having == null ? factory.emptyExpression() 
-	    		: _having.toKernelExpression(factory, _model);
+	    		: _having.toKernelExpression(factory, _model, this);
 	    
 	    evalOrdering(exps, factory);
 	//    exps.operation = QueryOperations.OP_SELECT;
@@ -199,6 +212,8 @@
 	      exps.projections = toValues(factory, getSelectionList());
 	//    exps.range = null; // Value[]
 	//    exps.resultClass = null; // Class
+	      if (_parameterTypes != null)
+	          exps.parameterTypes = _parameterTypes;
 	    return exps;
     }
 
@@ -214,7 +229,7 @@
             OrderImpl order = (OrderImpl)_orders.get(i);
             //Expression<? extends Comparable> expr = order.getExpression();
             //exps.ordering[i] = Expressions.toValue(
-            //    (ExpressionImpl<?>)expr, factory, _model);
+            //    (ExpressionImpl<?>)expr, factory, _model, this);
             
             //exps.orderingClauses[i] = assemble(firstChild);
             //exps.orderingAliases[i] = firstChild.text;
@@ -231,7 +246,7 @@
         for (int i = 0; i < groupByCount; i++) {
              Expression<?> groupBy = _groups.get(i);    
              exps.grouping[i] = Expressions.toValue(
-                 (ExpressionImpl<?>)groupBy, factory, _model);;
+                 (ExpressionImpl<?>)groupBy, factory, _model, this);;
         }
     }
     
@@ -244,9 +259,68 @@
     	Value[] result = new Value[sels.size()];
     	int i = 0;
     	for (Selection<?> s : sels) {
-    		result[i++] = ((ExpressionImpl<?>)s).toValue(factory, _model);
+    		result[i++] = ((ExpressionImpl<?>)s).toValue(factory, _model, 
+    		    this);
     	}
     	return result;
     }
 
+    void setImplicitTypes(Value val1, Value val2, Class<?> expected) {
+        Class<?> c1 = val1.getType();
+        Class<?> c2 = val2.getType();
+        boolean o1 = c1 == AbstractExpressionBuilder.TYPE_OBJECT;
+        boolean o2 = c2 == AbstractExpressionBuilder.TYPE_OBJECT;
+
+        if (o1 && !o2) {
+            val1.setImplicitType(c2);
+            if (val1.getMetaData() == null && !val1.isXPath())
+                val1.setMetaData(val2.getMetaData());
+        } else if (!o1 && o2) {
+            val2.setImplicitType(c1);
+            if (val2.getMetaData() == null && !val1.isXPath())
+                val2.setMetaData(val1.getMetaData());
+        } else if (o1 && o2 && expected != null) {
+            // we never expect a pc type, so don't bother with metadata
+            val1.setImplicitType(expected);
+            val2.setImplicitType(expected);
+        } else if (AbstractExpressionBuilder.isNumeric(val1.getType()) 
+            != AbstractExpressionBuilder.isNumeric(val2.getType())) {
+            AbstractExpressionBuilder.convertTypes(val1, val2);
+        }
+
+        // as well as setting the types for conversions, we also need to
+        // ensure that any parameters are declared with the correct type,
+        // since the JPA spec expects that these will be validated
+        org.apache.openjpa.kernel.exps.Parameter param =
+            val1 instanceof org.apache.openjpa.kernel.exps.Parameter ? 
+            (org.apache.openjpa.kernel.exps.Parameter) val1
+            : val2 instanceof org.apache.openjpa.kernel.exps.Parameter ? 
+            (org.apache.openjpa.kernel.exps.Parameter) val2 : null;
+        Path path = val1 instanceof Path ? (Path) val1
+            : val2 instanceof Path ? (Path) val2 : null;
+
+        // we only check for parameter-to-path comparisons
+        if (param == null || path == null || _parameterTypes == null)
+            return;
+
+        FieldMetaData fmd = path.last();
+        if (fmd == null)
+            return;
+
+        //TODO:
+        //if (expected == null)
+        //    checkEmbeddable(path);
+
+        Class<?> type = path.getType();
+        if (type == null)
+            return;
+
+        Object paramKey = param.getParameterKey();
+        if (paramKey == null)
+            return;
+
+        // make sure we have already declared the parameter
+        if (_parameterTypes.containsKey(paramKey))
+            _parameterTypes.put(paramKey, type);
+    }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java Mon May 18 15:56:35 2009
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.QueryBuilder.In;
@@ -39,12 +40,14 @@
 public abstract class ExpressionImpl<X> extends SelectionImpl<X> 
     implements Expression<X> {
 
-    Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+    Value toValue(ExpressionFactory factory, MetamodelImpl model,
+        CriteriaQuery q) {
         throw new AbstractMethodError(this.getClass().getName());
     }
     
     org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        ExpressionFactory factory, MetamodelImpl model) {
+        ExpressionFactory factory, MetamodelImpl model,
+        CriteriaQuery q) {
         throw new AbstractMethodError(this.getClass().getName());
     }
     

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java Mon May 18 15:56:35 2009
@@ -23,6 +23,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.QueryBuilder;
@@ -38,8 +39,8 @@
 public class Expressions {
 	
 	static Value toValue(ExpressionImpl<?> e, ExpressionFactory factory, 
-		MetamodelImpl model) {
-		Value v = e.toValue(factory, model);
+		MetamodelImpl model, CriteriaQuery q) {
+		Value v = e.toValue(factory, model, q);
 		return v;
 	}
 	
@@ -107,8 +108,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.abs(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.abs(Expressions.toValue(e, factory, model, q));
         }
     }
     
@@ -125,8 +127,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            Value v = factory.count(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            Value v = factory.count(Expressions.toValue(e, factory, model, q));
             return _distinct ? factory.distinct(v) : v;
         }
     }
@@ -137,8 +140,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.avg(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.avg(Expressions.toValue(e, factory, model, q));
         }
     }
     
@@ -148,8 +152,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.sqrt(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.sqrt(Expressions.toValue(e, factory, model, q));
         }
     }
     
@@ -159,8 +164,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.max(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.max(Expressions.toValue(e, factory, model, q));
         }
     }
 
@@ -170,8 +176,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.min(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.min(Expressions.toValue(e, factory, model, q));
         }
     }
     
@@ -185,8 +192,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.size(Expressions.toValue(e, factory, model));
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.size(Expressions.toValue(e, factory, model, q));
         }
     }
 
@@ -197,8 +205,9 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.cast(Expressions.toValue(e, factory, model), b);
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
+            return factory.cast(Expressions.toValue(e, factory, model, q), b);
         }
     }
     public static class Concat extends BinarayFunctionalExpression<String> {
@@ -215,10 +224,11 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.concat(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model));
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q));
         }
     }
     
@@ -246,11 +256,12 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return JPQLExpressionBuilder.convertSubstringArguments(factory, 
-            	Expressions.toValue(e, factory, model), 
-            	from == null ? null : from.toValue(factory, model), 
-            	len == null ? null : len.toValue(factory, model));
+            	Expressions.toValue(e, factory, model, q), 
+            	from == null ? null : from.toValue(factory, model, q), 
+            	len == null ? null : len.toValue(factory, model, q));
         }
     }
     
@@ -286,7 +297,8 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
     		Boolean spec = null;
     		if (ts != null) {
     			switch (ts) {
@@ -296,8 +308,8 @@
     			}
     		}
             return factory.trim(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model), spec);
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q), spec);
         }
     }
 
@@ -324,12 +336,13 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
     		return (e2 == null) 
-            ?   factory.sum(Expressions.toValue(e1, factory, model))
+            ?   factory.sum(Expressions.toValue(e1, factory, model, q))
     		:   factory.add(
-    			   Expressions.toValue(e1, factory, model), 
-    			   Expressions.toValue(e2, factory, model));
+    			   Expressions.toValue(e1, factory, model, q), 
+    			   Expressions.toValue(e2, factory, model, q));
         }
     }
     
@@ -349,10 +362,11 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.multiply(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model));
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q));
         }
     }
     
@@ -372,10 +386,11 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.subtract(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model));
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q));
         }
     }
 
@@ -396,10 +411,11 @@
     	}
     	
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.divide(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model));
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q));
         }
     }
 
@@ -417,10 +433,11 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.mod(
-            	Expressions.toValue(e1, factory, model), 
-            	Expressions.toValue(e2, factory, model));
+            	Expressions.toValue(e1, factory, model, q), 
+            	Expressions.toValue(e2, factory, model, q));
         }
     }
 
@@ -430,7 +447,8 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.getCurrentDate();
         }
     }
@@ -441,7 +459,8 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.getCurrentTime();
         }
     }
@@ -453,7 +472,8 @@
     	}
 
     	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             return factory.getCurrentTimestamp();
         }
     }
@@ -475,21 +495,21 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
             boolean isTypeExpr = false;
-            Value val1 = Expressions.toValue(e1, factory, model);
-            Value val2 = Expressions.toValue(e2, factory, model);
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q);
             if (e1 instanceof PathImpl) {
                 PathImpl path = (PathImpl)e1;
                 isTypeExpr = path.isTypeExpr();
                 if (isTypeExpr) {
                     ((Constant)e2).setTypeLit(isTypeExpr);
-                    val2 = Expressions.toValue(e2, factory, model);
+                    val2 = Expressions.toValue(e2, factory, model, q);
                     Class clzz = (Class)((Literal)val2).getValue();
                     val2.setMetaData(((Types.Managed)model.type(clzz)).meta);
                 }
             }
-            
+            ((CriteriaQueryImpl)q).setImplicitTypes(val1, val2, null);
             if (!negate)
                 return factory.equal(val1, val2);
             else
@@ -508,10 +528,10 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
                 return factory.greaterThan(
-                	Expressions.toValue(e1, factory, model), 
-                	Expressions.toValue(e2, factory, model));
+                	Expressions.toValue(e1, factory, model, q), 
+                	Expressions.toValue(e2, factory, model, q));
         }
     }
     
@@ -526,10 +546,10 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
                 return factory.greaterThanEqual(
-                    Expressions.toValue(e1, factory, model), 
-                    Expressions.toValue(e2, factory, model));
+                    Expressions.toValue(e1, factory, model, q), 
+                    Expressions.toValue(e2, factory, model, q));
         }
     }
 
@@ -545,10 +565,10 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
                 return factory.lessThan(
-                    Expressions.toValue(e1, factory, model), 
-                    Expressions.toValue(e2, factory, model));
+                    Expressions.toValue(e1, factory, model, q), 
+                    Expressions.toValue(e2, factory, model, q));
         }
     }
     
@@ -563,10 +583,10 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
                 return factory.lessThanEqual(
-                	Expressions.toValue(e1, factory, model), 
-                    Expressions.toValue(e2, factory, model));
+                	Expressions.toValue(e1, factory, model, q), 
+                    Expressions.toValue(e2, factory, model, q));
 
         }
     }
@@ -601,7 +621,8 @@
         }
         
         @Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQuery q) {
             if (!typeLit)
                 return factory.newLiteral(arg, 1);
             else
@@ -625,13 +646,14 @@
     	
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        	ExpressionFactory factory, MetamodelImpl model) {
+        	ExpressionFactory factory, MetamodelImpl model, 
+        	CriteriaQuery q) {
             if (!negate)
                 return factory.isEmpty(
-                    Expressions.toValue(collection, factory, model));
+                    Expressions.toValue(collection, factory, model, q));
             else
                 return factory.isNotEmpty(
-                    Expressions.toValue(collection, factory, model));
+                    Expressions.toValue(collection, factory, model, q));
         }
     }
     
@@ -661,10 +683,11 @@
     	
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        	ExpressionFactory factory, MetamodelImpl model) {
+        	ExpressionFactory factory, MetamodelImpl model, 
+        	CriteriaQuery q) {
             return factory.contains(
-                Expressions.toValue(collection, factory, model), 
-                Expressions.toValue(element, factory, model));
+                Expressions.toValue(collection, factory, model, q), 
+                Expressions.toValue(element, factory, model, q));
         }
     }
     
@@ -704,11 +727,12 @@
 
     	@Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        	ExpressionFactory factory, MetamodelImpl model) {
+        	ExpressionFactory factory, MetamodelImpl model, 
+        	CriteriaQuery q) {
             return factory.matches(
-            	Expressions.toValue(str, factory, model), 
-            	Expressions.toValue(pattern, factory, model), "_", "%", 
-            	Expressions.toValue(escapeChar, factory, model).toString());
+            	Expressions.toValue(str, factory, model, q), 
+            	Expressions.toValue(pattern, factory, model, q), "_", "%", 
+            	Expressions.toValue(escapeChar, factory, model, q).toString());
         }
     }
     
@@ -737,12 +761,13 @@
     	
     	@Override
         public org.apache.openjpa.kernel.exps.Value toValue(
-        	ExpressionFactory factory, MetamodelImpl model) {
+        	ExpressionFactory factory, MetamodelImpl model, 
+        	CriteriaQuery q) {
     		Value[] vs = new Value[values.size()];
     		int i = 0;
     		for (Expression<?> e : values)
     	        vs[i++] = Expressions.toValue((ExpressionImpl<?>)e, 
-    	           factory, model);
+    	           factory, model, q);
             return factory.coalesceExpression(vs);
         }
     }
@@ -756,9 +781,9 @@
     	
     	@Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
     		return factory.equal(
-    			Expressions.toValue(e, factory, model), 
+    			Expressions.toValue(e, factory, model, q), 
     			factory.getNull());
     	}
     }
@@ -772,9 +797,9 @@
     	
     	@Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
     		return factory.notEqual(
-    			Expressions.toValue(e, factory, model), 
+    			Expressions.toValue(e, factory, model, q), 
     			factory.getNull());
     	}
     }
@@ -804,11 +829,11 @@
     
     	@Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model) {
+            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
     		IsNotNull notNull = new Expressions.IsNotNull(e);
     		return factory.and(
-     		    super.toKernelExpression(factory, model),
-    		    notNull.toKernelExpression(factory, model));
+     		    super.toKernelExpression(factory, model, q),
+    		    notNull.toKernelExpression(factory, model, q));
     	}
     }
     
@@ -857,21 +882,22 @@
 
         @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
-                ExpressionFactory factory, MetamodelImpl model) {
+                ExpressionFactory factory, MetamodelImpl model, 
+                CriteriaQuery q) {
             int size = whens.size();
             org.apache.openjpa.kernel.exps.Expression[] exps = 
                 new org.apache.openjpa.kernel.exps.Expression[size];
             for (int i = 0; i < size; i++) {
                 org.apache.openjpa.kernel.exps.Expression expr = 
                     ((Expressions.BinaryLogicalExpression)whens.get(i)).
-                    toKernelExpression(factory, model);
+                    toKernelExpression(factory, model, q);
                 Value action = Expressions.toValue(
-                        (ExpressionImpl<?>)thens.get(i), factory, model);
+                        (ExpressionImpl<?>)thens.get(i), factory, model, q);
                 exps[i] = factory.whenCondition(expr, action);
             }
 
             Value other = Expressions.toValue(
-                    (ExpressionImpl<?>)otherwise, factory, model);
+                    (ExpressionImpl<?>)otherwise, factory, model, q);
             return factory.generalCaseExpression(exps, other);
         }
     }
@@ -929,9 +955,10 @@
 
         @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
-                ExpressionFactory factory, MetamodelImpl model) {
+                ExpressionFactory factory, MetamodelImpl model, 
+                CriteriaQuery q) {
             Value caseOperandExpr = Expressions.toValue(
-                (ExpressionImpl<?>)caseOperand, factory, model);
+                (ExpressionImpl<?>)caseOperand, factory, model, q);
             int size = whens.size();
             org.apache.openjpa.kernel.exps.Expression[] exps = 
                 new org.apache.openjpa.kernel.exps.Expression[size];
@@ -940,12 +967,12 @@
                 //TODO: Boolean literal, String literal    
                 val = factory.newLiteral(whens.get(i), Literal.TYPE_NUMBER);
                 Value action = Expressions.toValue(
-                        (ExpressionImpl<?>)thens.get(i), factory, model);
+                        (ExpressionImpl<?>)thens.get(i), factory, model, q);
                 exps[i] = factory.whenScalar(val, action);
             }
 
             Value other = Expressions.toValue(
-                    (ExpressionImpl<?>)otherwise, factory, model);
+                    (ExpressionImpl<?>)otherwise, factory, model, q);
             return factory.simpleCaseExpression(caseOperandExpr, exps, other);
         }
     }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java Mon May 18 15:56:35 2009
@@ -18,7 +18,14 @@
  */
 package org.apache.openjpa.persistence.criteria;
 
+import java.util.Collection;
 import javax.persistence.Parameter;
+import javax.persistence.criteria.CriteriaQuery;
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.kernel.exps.ExpressionFactory;
+import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.meta.MetamodelImpl;
 
 /**
  * Parameter of a criteria query.
@@ -48,4 +55,40 @@
 		return position;
 	}
 
+    @Override
+    public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+        CriteriaQuery q) {
+        boolean positional = false;
+        LinkedMap parameterTypes = ((CriteriaQueryImpl)q).getParameterTypes();
+        if (parameterTypes == null) {
+            parameterTypes = new LinkedMap(6);
+            ((CriteriaQueryImpl)q).setParameterTypes(parameterTypes);
+        } 
+        if (name == null) {
+            position = parameterTypes.size() + 1;
+            positional = true;
+        }
+        
+        Object paramKey = name == null ? Integer.valueOf(position) : name;
+        if (!parameterTypes.containsKey(paramKey))
+            parameterTypes.put(paramKey, Object.class);
+
+        ClassMetaData meta = null;
+        Class clzz = getJavaType();
+        int index;
+        if (positional) 
+            index = position - 1;
+        else 
+            // otherwise the index is just the current size of the params
+            index = parameterTypes.indexOf(paramKey);
+        
+        boolean isCollectionValued  = Collection.class.isAssignableFrom(clzz);
+        org.apache.openjpa.kernel.exps.Parameter param = isCollectionValued 
+            ? factory.newCollectionValuedParameter(paramKey, Object.class) 
+            : factory.newParameter(paramKey, Object.class);
+        param.setMetaData(meta);
+        param.setIndex(index);
+        
+        return param;
+    }	
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java Mon May 18 15:56:35 2009
@@ -19,6 +19,7 @@
 
 package org.apache.openjpa.persistence.criteria;
 
+import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Path;
 import javax.persistence.metamodel.AbstractCollection;
@@ -65,12 +66,13 @@
     }
     
     @Override
-    public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
+    public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+        CriteriaQuery q) {
         Value var = null;
         if (_parent != null) { 
             org.apache.openjpa.kernel.exps.Path path = 
                 (org.apache.openjpa.kernel.exps.Path)
-                _parent.toValue(factory, model);
+                _parent.toValue(factory, model, q);
             path.get(member.fmd, false);
             var = path;
         } else {

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java?rev=775997&r1=775996&r2=775997&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java Mon May 18 15:56:35 2009
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 
@@ -80,18 +81,18 @@
     
     @Override
     org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        ExpressionFactory factory, MetamodelImpl model) {
+        ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
     		if (_exps == null || _exps.isEmpty())
     			return factory.emptyExpression();
     		if (_exps.size() == 1)
     			return ((ExpressionImpl<?>)_exps.get(0))
-    			   .toKernelExpression(factory, model);
+    			   .toKernelExpression(factory, model, q);
     		ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0);
     		ExpressionImpl<?> e2 = (ExpressionImpl<?>)_exps.get(1);
     		org.apache.openjpa.kernel.exps.Expression ke1 = 
-    			e1.toKernelExpression(factory, model);
+    			e1.toKernelExpression(factory, model, q);
     		org.apache.openjpa.kernel.exps.Expression ke2 = 
-    			e2.toKernelExpression(factory, model);
+    			e2.toKernelExpression(factory, model, q);
     		org.apache.openjpa.kernel.exps.Expression result = 
     			_op == BooleanOperator.AND 
     			? factory.and(ke1,ke2) : factory.or(ke1, ke2);
@@ -99,8 +100,8 @@
     		for (int i = 2; i < _exps.size(); i++) {
     			ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i);
     			result = _op == BooleanOperator.AND 
-                ? factory.and(result, e.toKernelExpression(factory, model))
-    		    : factory.or(result, e.toKernelExpression(factory, model));
+                ? factory.and(result, e.toKernelExpression(factory, model, q))
+    		    : factory.or(result, e.toKernelExpression(factory,model,q));
     		}
     		return _negated ? factory.not(result) : result;
     }