From df7f6ddd82e600d2d00606236b078051216bbb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Mon, 11 Oct 2010 13:06:09 +0000 Subject: [PATCH] #658206 : Added any() accessor --- .../java/com/mysema/query/alias/Alias.java | 8 ++-- .../query/alias/DefaultPathFactory.java | 6 ++- .../query/codegen/EntitySerializer.java | 13 +++-- .../mysema/query/types/ExpressionUtils.java | 2 +- .../query/types/PredicateOperation.java | 2 +- .../query/types/SubQueryExpressionImpl.java | 2 +- .../query/types/expr/ArrayExpression.java | 2 +- .../mysema/query/types/expr/CaseBuilder.java | 2 +- .../query/types/expr/CaseForEqBuilder.java | 2 +- .../types/expr/CollectionExpressionBase.java | 30 ++++++++++-- .../com/mysema/query/types/path/BeanPath.java | 12 +++-- .../query/types/path/CollectionPath.java | 47 ++++++++++++------- .../mysema/query/types/path/Constants.java | 6 ++- .../com/mysema/query/types/path/ListPath.java | 45 ++++++++++-------- .../com/mysema/query/types/path/MapPath.java | 4 +- .../mysema/query/types/path/PathBuilder.java | 36 ++++++++++++-- .../com/mysema/query/types/path/SetPath.java | 45 ++++++++++++------ .../query/ExtendedSubQueryExpression.java | 2 + .../query/types/query/ListSubQuery.java | 7 ++- .../query/types/path/CollectionPathTest.java | 21 +++++++++ .../mysema/query/types/path/ListPathTest.java | 22 +++++++++ .../mysema/query/types/path/SetPathTest.java | 21 +++++++++ .../mysema/query/jdo/JDOQLMethodsTest.java | 2 +- .../mysema/query/jdo/test/domain/QStore.java | 2 +- 24 files changed, 258 insertions(+), 83 deletions(-) create mode 100644 querydsl-core/src/test/java/com/mysema/query/types/path/CollectionPathTest.java create mode 100644 querydsl-core/src/test/java/com/mysema/query/types/path/ListPathTest.java create mode 100644 querydsl-core/src/test/java/com/mysema/query/types/path/SetPathTest.java diff --git a/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java b/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java index 618506848..6dd33d14b 100644 --- a/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java +++ b/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java @@ -72,8 +72,8 @@ public final class Alias { return aliasFactory.> getCurrentAndReset(); } - public static CollectionPath $(Collection args) { - return aliasFactory.> getCurrentAndReset(); + public static CollectionPath $(Collection args) { + return aliasFactory.> getCurrentAndReset(); } public static > ComparablePath $(D arg) { @@ -127,8 +127,8 @@ public final class Alias { return aliasFactory.> getCurrentAndReset(); } - public static SetPath $(Set args) { - return aliasFactory.> getCurrentAndReset(); + public static SetPath $(Set args) { + return aliasFactory.> getCurrentAndReset(); } public static NumberPath $(Short arg) { diff --git a/querydsl-core/src/main/java/com/mysema/query/alias/DefaultPathFactory.java b/querydsl-core/src/main/java/com/mysema/query/alias/DefaultPathFactory.java index 55a8369f9..b88799867 100644 --- a/querydsl-core/src/main/java/com/mysema/query/alias/DefaultPathFactory.java +++ b/querydsl-core/src/main/java/com/mysema/query/alias/DefaultPathFactory.java @@ -30,9 +30,10 @@ public class DefaultPathFactory implements PathFactory{ return new BooleanPath(metadata); } + @SuppressWarnings("unchecked") @Override public Path> createCollectionPath(Class elementType, PathMetadata metadata) { - return new CollectionPath(elementType, elementType.getSimpleName(), metadata); + return new CollectionPath>(elementType, (Class)EntityPathBase.class, metadata); } @Override @@ -77,9 +78,10 @@ public class DefaultPathFactory implements PathFactory{ return new NumberPath(type, metadata); } + @SuppressWarnings("unchecked") @Override public Path> createSetPath(Class elementType, PathMetadata metadata) { - return new SetPath(elementType, elementType.getName(), metadata); + return new SetPath>(elementType, (Class)EntityPathBase.class, metadata); } @Override diff --git a/querydsl-core/src/main/java/com/mysema/query/codegen/EntitySerializer.java b/querydsl-core/src/main/java/com/mysema/query/codegen/EntitySerializer.java index 6a45c1b89..e106e94bf 100644 --- a/querydsl-core/src/main/java/com/mysema/query/codegen/EntitySerializer.java +++ b/querydsl-core/src/main/java/com/mysema/query/codegen/EntitySerializer.java @@ -627,6 +627,7 @@ public class EntitySerializer implements Serializer{ // strips of "? extends " etc Type propertyType = new SimpleType(property.getType(), property.getType().getParameters()); Type queryType = typeMappings.getPathType(propertyType, model, false); + Type genericQueryType = null; String localRawName = writer.getRawName(property.getType()); switch(property.getType().getCategory()){ @@ -664,17 +665,23 @@ public class EntitySerializer implements Serializer{ serialize(model, property, new ClassType(ArrayPath.class, property.getType().getComponentType()), writer, "createArray", localRawName + DOT_CLASS); break; case COLLECTION: + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); localRawName = writer.getRawName(property.getParameter(0)); - serialize(model, property, new ClassType(CollectionPath.class, getRaw(property.getParameter(0))), writer, "createCollection", localRawName + DOT_CLASS); + queryType = typeMappings.getPathType(property.getParameter(0), model, true); + + serialize(model, property, new ClassType(CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), writer, "createCollection", localRawName + DOT_CLASS, writer.getRawName(queryType) + DOT_CLASS); break; case SET: + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); localRawName = writer.getRawName(property.getParameter(0)); - serialize(model, property, new ClassType(SetPath.class, getRaw(property.getParameter(0))), writer, "createSet", localRawName + DOT_CLASS); + queryType = typeMappings.getPathType(property.getParameter(0), model, true); + + serialize(model, property, new ClassType(SetPath.class, getRaw(property.getParameter(0)), genericQueryType), writer, "createSet", localRawName + DOT_CLASS, writer.getRawName(queryType) + DOT_CLASS); break; case MAP: String genericKey = writer.getGenericName(true, property.getParameter(0)); String genericValue = writer.getGenericName(true, property.getParameter(1)); - Type genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(1)), model, false); + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(1)), model, false); String keyType = writer.getRawName(property.getParameter(0)); String valueType = writer.getRawName(property.getParameter(1)); queryType = typeMappings.getPathType(property.getParameter(1), model, true); diff --git a/querydsl-core/src/main/java/com/mysema/query/types/ExpressionUtils.java b/querydsl-core/src/main/java/com/mysema/query/types/ExpressionUtils.java index 8eeff30fe..f3cbcb6a9 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/ExpressionUtils.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/ExpressionUtils.java @@ -11,7 +11,7 @@ import javax.annotation.Nullable; /** - * Utilities for constructing common operation instances + * ExpressionUtils provides utilities for constructing common operation instances * * @author tiwe * diff --git a/querydsl-core/src/main/java/com/mysema/query/types/PredicateOperation.java b/querydsl-core/src/main/java/com/mysema/query/types/PredicateOperation.java index 63d03534a..3026f72a0 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/PredicateOperation.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/PredicateOperation.java @@ -8,7 +8,7 @@ package com.mysema.query.types; import javax.annotation.Nullable; /** - * PredicateOperation provides a Boolean typed Operation implemenentation + * PredicateOperation provides a Boolean typed Operation implementation * * @author tiwe * diff --git a/querydsl-core/src/main/java/com/mysema/query/types/SubQueryExpressionImpl.java b/querydsl-core/src/main/java/com/mysema/query/types/SubQueryExpressionImpl.java index e0ec900a8..16e66b622 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/SubQueryExpressionImpl.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/SubQueryExpressionImpl.java @@ -8,7 +8,7 @@ package com.mysema.query.types; import com.mysema.query.QueryMetadata; /** - * SubQueryImpl is the default implementation of the SubQuery interface + * SubQueryExpressionImpl is the default implementation of the SubQueryExpression interface * * @author tiwe * diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/ArrayExpression.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/ArrayExpression.java index 420028888..546358dfc 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/ArrayExpression.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/ArrayExpression.java @@ -16,7 +16,7 @@ import com.mysema.query.types.Expression; * * @param */ -public interface ArrayExpression { +public interface ArrayExpression extends Expression{ /** * Get the size of the array diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseBuilder.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseBuilder.java index 84e10b58b..4cf7cdc1c 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseBuilder.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseBuilder.java @@ -21,7 +21,7 @@ import com.mysema.query.types.Ops; * e.g. * *
- * Expr<String> cases = new CaseBuilder()
+ * Expression<String> cases = new CaseBuilder()
  *     .when(c.annualSpending.gt(10000)).then("Premier")
  *     .when(c.annualSpending.gt(5000)).then("Gold")
  *     .when(c.annualSpending.gt(2000)).then("Silver")
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseForEqBuilder.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseForEqBuilder.java
index ae9d41d18..c790e0e27 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseForEqBuilder.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/CaseForEqBuilder.java
@@ -22,7 +22,7 @@ import com.mysema.query.types.Ops;
  *
  * 
  * QCustomer c = QCustomer.customer;
- * Expr cases = c.annualSpending
+ * Expression<Integer> cases = c.annualSpending
  *     .when(1000l).then(1)
  *     .when(2000l).then(2)
  *     .when(5000l).then(3)
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/CollectionExpressionBase.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/CollectionExpressionBase.java
index 20f949109..2e29e83a0 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/expr/CollectionExpressionBase.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/CollectionExpressionBase.java
@@ -5,6 +5,8 @@
  */
 package com.mysema.query.types.expr;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Collection;
 
 import javax.annotation.Nullable;
@@ -13,9 +15,10 @@ import com.mysema.query.types.CollectionExpression;
 import com.mysema.query.types.ConstantImpl;
 import com.mysema.query.types.Expression;
 import com.mysema.query.types.Ops;
+import com.mysema.query.types.PathMetadata;
 
 /**
- * CollectionExpressionBase is an abstract base class for ECollection implementations
+ * CollectionExpressionBase is an abstract base class for CollectionExpression implementations
  *
  * @author tiwe
  *
@@ -30,11 +33,16 @@ public abstract class CollectionExpressionBase, E> exten
 
     @Nullable
     private volatile NumberExpression size;
-
+    
+    @Nullable
+    private transient volatile Constructor constructor;
+    
     public CollectionExpressionBase(Class type) {
         super(type);
     }
 
+    public abstract SimpleExpression any();
+    
     public final BooleanExpression contains(E child) {
         return contains(new ConstantImpl(child));
     }
@@ -63,6 +71,22 @@ public abstract class CollectionExpressionBase, E> exten
         return size;
     }
 
-    
+    @SuppressWarnings("unchecked")
+    protected > Q newInstance(Class queryType, boolean typed, PathMetadata pm) throws NoSuchMethodException,
+        InstantiationException, IllegalAccessException,
+        InvocationTargetException {
+        if (constructor == null) {
+            if (typed){
+                constructor = queryType.getConstructor(Class.class, PathMetadata.class);
+            }else{
+                constructor = queryType.getConstructor(PathMetadata.class);
+            }
+        }
+        if (typed){
+            return (Q)constructor.newInstance(getElementType(), pm);
+        }else{
+            return (Q)constructor.newInstance(pm);
+        }
+    }
     
 }
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/BeanPath.java b/querydsl-core/src/main/java/com/mysema/query/types/path/BeanPath.java
index 10f931213..3a2503923 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/BeanPath.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/BeanPath.java
@@ -139,10 +139,11 @@ public class BeanPath extends SimpleExpression implements Path {
      * @param type
      * @return
      */
-    protected  CollectionPath createCollection(String property, Class type) {
-        return add(new CollectionPath(type, type.getSimpleName(), forProperty(property)));
+    @SuppressWarnings("unchecked")
+    protected > CollectionPath createCollection(String property, Class type, Class queryType) {
+        return add(new CollectionPath(type, (Class) queryType, forProperty(property)));
     }
-
+    
     /**
      * Create a new Comparable typed path
      *
@@ -247,8 +248,9 @@ public class BeanPath extends SimpleExpression implements Path {
      * @param type
      * @return
      */
-    protected  SetPath createSet(String property, Class type) {
-        return add(new SetPath(type, type.getSimpleName(), forProperty(property)));
+    @SuppressWarnings("unchecked")
+    protected > SetPath createSet(String property, Class type, Class queryType) {
+        return add(new SetPath(type, (Class) queryType, forProperty(property)));
     }
 
     /**
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/CollectionPath.java b/querydsl-core/src/main/java/com/mysema/query/types/path/CollectionPath.java
index 9c2b9a2b4..aad11294e 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/CollectionPath.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/CollectionPath.java
@@ -6,14 +6,19 @@
 package com.mysema.query.types.path;
 
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Collection;
 
+import javax.annotation.Nullable;
+
 import com.mysema.commons.lang.Assert;
+import com.mysema.query.types.ExpressionException;
 import com.mysema.query.types.Path;
 import com.mysema.query.types.PathImpl;
 import com.mysema.query.types.PathMetadata;
 import com.mysema.query.types.Visitor;
 import com.mysema.query.types.expr.CollectionExpressionBase;
+import com.mysema.query.types.expr.SimpleExpression;
 
 /**
  * CollectionPath represents collection paths
@@ -22,21 +27,24 @@ import com.mysema.query.types.expr.CollectionExpressionBase;
  *
  * @param  component type
  */
-public class CollectionPath extends CollectionExpressionBase,E> implements Path> {
+public class CollectionPath> extends CollectionExpressionBase,E> implements Path>{    
 
     private static final long serialVersionUID = -4982311799113762600L;
 
     private final Class elementType;
 
-    private final String entityName;
-
     private final Path> pathMixin;
 
+    @Nullable
+    private transient Q any;
+    
+    private final Class queryType;
+    
     @SuppressWarnings("unchecked")
-    public CollectionPath(Class type, String entityName, PathMetadata metadata) {
+    public CollectionPath(Class type, Class queryType, PathMetadata metadata) {
         super((Class)Collection.class);
         this.elementType = (Class) Assert.notNull(type,"type");
-        this.entityName = Assert.notNull(entityName,"entityName");
+        this.queryType = queryType;
         this.pathMixin = new PathImpl>((Class)Collection.class, metadata);
     }
 
@@ -44,6 +52,24 @@ public class CollectionPath extends CollectionExpressionBase,E>
     public  R accept(Visitor v, C context) {
         return v.visit(this, context);
     }
+    
+    @Override
+    public Q any(){
+        if (any == null){
+            try {
+                any = newInstance(queryType, Constants.isTyped(queryType), pathMixin.getMetadata());
+            } catch (NoSuchMethodException e) {
+                throw new ExpressionException(e);
+            } catch (InstantiationException e) {
+                throw new ExpressionException(e);
+            } catch (IllegalAccessException e) {
+                throw new ExpressionException(e);
+            } catch (InvocationTargetException e) {
+                throw new ExpressionException(e);
+            }
+        }
+        return any;
+    }
 
     @Override
     public boolean equals(Object o) {
@@ -54,15 +80,6 @@ public class CollectionPath extends CollectionExpressionBase,E>
         return elementType;
     }
 
-    /**
-     * Get the entity name for this Entity collection path
-     *
-     * @return
-     */
-    public String getEntityName() {
-        return entityName;
-    }
-
     @Override
     public PathMetadata getMetadata() {
         return pathMixin.getMetadata();
@@ -91,7 +108,5 @@ public class CollectionPath extends CollectionExpressionBase,E>
             throw new IndexOutOfBoundsException(String.valueOf(index));
         }
     }
-
-    
     
 }
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/Constants.java b/querydsl-core/src/main/java/com/mysema/query/types/path/Constants.java
index ef3d29b27..2316218fa 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/Constants.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/Constants.java
@@ -11,7 +11,7 @@ import java.util.Set;
 
 public final class Constants {
     
-    static final Set> typedClasses = new HashSet>(Arrays.>asList(
+    private static final Set> typedClasses = new HashSet>(Arrays.>asList(
             PathBuilder.class,
             ComparablePath.class,
             EnumPath.class,
@@ -24,6 +24,10 @@ public final class Constants {
             TimePath.class
             ));
     
+    public static boolean isTyped(Class cl){
+        return typedClasses.contains(cl);
+    }
+    
     private Constants(){}
 
 }
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/ListPath.java b/querydsl-core/src/main/java/com/mysema/query/types/path/ListPath.java
index d30476a84..fe29a6ca9 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/ListPath.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/ListPath.java
@@ -6,7 +6,6 @@
 package com.mysema.query.types.path;
 
 import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
 import java.util.List;
@@ -18,9 +17,9 @@ import com.mysema.commons.lang.Assert;
 import com.mysema.query.types.Expression;
 import com.mysema.query.types.ExpressionException;
 import com.mysema.query.types.Path;
+import com.mysema.query.types.PathImpl;
 import com.mysema.query.types.PathMetadata;
 import com.mysema.query.types.PathMetadataFactory;
-import com.mysema.query.types.PathImpl;
 import com.mysema.query.types.Visitor;
 import com.mysema.query.types.expr.CollectionExpressionBase;
 import com.mysema.query.types.expr.ListExpression;
@@ -46,7 +45,7 @@ public class ListPath> extends CollectionExpres
     private final Class queryType;
 
     @Nullable
-    private transient Constructor constructor;
+    private transient Q any;    
 
     @SuppressWarnings("unchecked")
     public ListPath(Class elementType, Class queryType, PathMetadata metadata) {
@@ -60,6 +59,24 @@ public class ListPath> extends CollectionExpres
     public  R accept(Visitor v, C context) {
         return v.visit(this, context);
     }
+    
+    @Override
+    public Q any(){
+        if (any == null){
+            try {
+                any = newInstance(pathMixin.getMetadata());
+            } catch (NoSuchMethodException e) {
+                throw new ExpressionException(e);
+            } catch (InstantiationException e) {
+                throw new ExpressionException(e);
+            } catch (IllegalAccessException e) {
+                throw new ExpressionException(e);
+            } catch (InvocationTargetException e) {
+                throw new ExpressionException(e);
+            }
+        }
+        return any;
+    }
 
     protected PathMetadata forListAccess(int index){
         return PathMetadataFactory.forListAccess(this, index);
@@ -105,6 +122,11 @@ public class ListPath> extends CollectionExpres
         }
     }
 
+    private Q newInstance(PathMetadata md) throws NoSuchMethodException, InstantiationException, 
+        IllegalAccessException, InvocationTargetException {
+        return newInstance(queryType, Constants.isTyped(queryType), md);
+    }
+
     @Override
     public Q get(int index) {
         if (cache.containsKey(index)){
@@ -140,23 +162,6 @@ public class ListPath> extends CollectionExpres
         return pathMixin.getAnnotatedElement();
     }
 
-    private Q newInstance(PathMetadata pm) throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException,
-            InvocationTargetException {
-        if (constructor == null) {
-            if (Constants.typedClasses.contains(queryType)){
-                constructor = queryType.getConstructor(Class.class, PathMetadata.class);
-            }else{
-                constructor = queryType.getConstructor(PathMetadata.class);
-            }
-        }
-        if (Constants.typedClasses.contains(queryType)){
-            return constructor.newInstance(getElementType(), pm);
-        }else{
-            return constructor.newInstance(pm);
-        }
-    }
-
     @Override
     public Class getParameter(int index) {
         if (index == 0){
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/MapPath.java b/querydsl-core/src/main/java/com/mysema/query/types/path/MapPath.java
index 4496db8f0..40994644e 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/MapPath.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/MapPath.java
@@ -136,13 +136,13 @@ public class MapPath> extends MapExpressionB
         InstantiationException, IllegalAccessException,
         InvocationTargetException {
         if (constructor == null){
-            if (Constants.typedClasses.contains(queryType)){
+            if (Constants.isTyped(queryType)){
                 constructor = queryType.getConstructor(Class.class, PathMetadata.class);
             }else{
                 constructor = queryType.getConstructor(PathMetadata.class);
             }
         }
-        if (Constants.typedClasses.contains(queryType)){
+        if (Constants.isTyped(queryType)){
             return constructor.newInstance(getValueType(), pm);
         }else{
             return constructor.newInstance(pm);
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/PathBuilder.java b/querydsl-core/src/main/java/com/mysema/query/types/path/PathBuilder.java
index a874b0ac1..89aed03c7 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/PathBuilder.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/PathBuilder.java
@@ -118,8 +118,22 @@ public final class PathBuilder extends EntityPathBase {
      * @param type
      * @return
      */
-    public  CollectionPath getCollection(String property, Class type) {
-        return super.createCollection(property, type);
+    public  CollectionPath> getCollection(String property, Class type) {
+        return super.createCollection(property, type, PathBuilder.class);
+    }
+
+    /**
+     * Get a new Collection typed path
+     *
+     * @param 
+     * @param 
+     * @param property property name
+     * @param type
+     * @param queryType
+     * @return
+     */
+    public > CollectionPath getCollection(String property, Class type, Class queryType) {
+        return super.createCollection(property, type, queryType);
     }
 
     /**
@@ -274,10 +288,24 @@ public final class PathBuilder extends EntityPathBase {
      * @param type
      * @return
      */
-    public  SetPath getSet(String property, Class type) {
-        return super.createSet(property, type);
+    public  SetPath> getSet(String property, Class type) {
+        return super.createSet(property, type, PathBuilder.class);
     }
 
+    /**
+     * Get a new Set typed path
+     *
+     * @param 
+     * @param 
+     * @param property property name
+     * @param type
+     * @param queryType
+     * @return
+     */
+    public > SetPath getSet(String property, Class type, Class queryType) {
+        return super.createSet(property, type, queryType);
+    }
+    
     /**
      * @param 
      * @param path
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/SetPath.java b/querydsl-core/src/main/java/com/mysema/query/types/path/SetPath.java
index 0b0e4dedd..ff8040d8a 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/path/SetPath.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/path/SetPath.java
@@ -6,14 +6,19 @@
 package com.mysema.query.types.path;
 
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Set;
 
+import javax.annotation.Nullable;
+
 import com.mysema.commons.lang.Assert;
+import com.mysema.query.types.ExpressionException;
 import com.mysema.query.types.Path;
 import com.mysema.query.types.PathMetadata;
 import com.mysema.query.types.PathImpl;
 import com.mysema.query.types.Visitor;
 import com.mysema.query.types.expr.CollectionExpressionBase;
+import com.mysema.query.types.expr.SimpleExpression;
 
 /**
  * SetPath represents set paths
@@ -22,21 +27,24 @@ import com.mysema.query.types.expr.CollectionExpressionBase;
  *
  * @param  component type
  */
-public class SetPath extends CollectionExpressionBase,E> implements Path> {
+public class SetPath> extends CollectionExpressionBase,E> implements Path> {
 
     private static final long serialVersionUID = 4145848445507037373L;
 
     private final Class elementType;
 
-    private final String entityName;
-
     private final Path> pathMixin;
+    
+    @Nullable
+    private transient Q any;
+    
+    private final Class queryType;
 
     @SuppressWarnings("unchecked")
-    public SetPath(Class type, String entityName, PathMetadata metadata) {
+    public SetPath(Class type, Class queryType, PathMetadata metadata) {
         super((Class)Set.class);
         this.elementType = (Class) Assert.notNull(type,"type");
-        this.entityName = Assert.notNull(entityName,"entityName");
+        this.queryType = queryType;
         this.pathMixin = new PathImpl>((Class)Set.class, metadata);
     }
 
@@ -44,6 +52,24 @@ public class SetPath extends CollectionExpressionBase,E> implements Pa
     public  R accept(Visitor v, C context) {
         return v.visit(this, context);
     }
+    
+    @Override
+    public Q any(){
+        if (any == null){
+            try {
+                any = newInstance(queryType, Constants.isTyped(queryType), pathMixin.getMetadata());
+            } catch (NoSuchMethodException e) {
+                throw new ExpressionException(e);
+            } catch (InstantiationException e) {
+                throw new ExpressionException(e);
+            } catch (IllegalAccessException e) {
+                throw new ExpressionException(e);
+            } catch (InvocationTargetException e) {
+                throw new ExpressionException(e);
+            }
+        }
+        return any;
+    }
 
     @Override
     public boolean equals(Object o) {
@@ -54,15 +80,6 @@ public class SetPath extends CollectionExpressionBase,E> implements Pa
         return elementType;
     }
 
-    /**
-     * Get the entity name for this Entity collection path
-     *
-     * @return
-     */
-    public String getEntityName() {
-        return entityName;
-    }
-
     @Override
     public PathMetadata getMetadata() {
         return pathMixin.getMetadata();
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/query/ExtendedSubQueryExpression.java b/querydsl-core/src/main/java/com/mysema/query/types/query/ExtendedSubQueryExpression.java
index 790fe8cae..02b4c96a3 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/query/ExtendedSubQueryExpression.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/query/ExtendedSubQueryExpression.java
@@ -4,6 +4,8 @@ import com.mysema.query.types.SubQueryExpression;
 import com.mysema.query.types.expr.BooleanExpression;
 
 /**
+ * Extensions to the SubQueryExpression interface
+ * 
  * @author tiwe
  *
  * @param 
diff --git a/querydsl-core/src/main/java/com/mysema/query/types/query/ListSubQuery.java b/querydsl-core/src/main/java/com/mysema/query/types/query/ListSubQuery.java
index e6649fbd7..848968ffc 100644
--- a/querydsl-core/src/main/java/com/mysema/query/types/query/ListSubQuery.java
+++ b/querydsl-core/src/main/java/com/mysema/query/types/query/ListSubQuery.java
@@ -38,7 +38,7 @@ public final class ListSubQuery extends CollectionExpressionBase,A> i
     
     @Nullable
     private volatile BooleanExpression exists;
-
+    
     @SuppressWarnings("unchecked")
     public ListSubQuery(Class elementType, QueryMetadata md) {
         super((Class)List.class);
@@ -50,6 +50,11 @@ public final class ListSubQuery extends CollectionExpressionBase,A> i
     public  R accept(Visitor v, C context) {
         return v.visit(this, context);
     }
+    
+    @Override
+    public SimpleExpression any(){
+        throw new UnsupportedOperationException();
+    }
 
     @Override
     public boolean equals(Object o) {
diff --git a/querydsl-core/src/test/java/com/mysema/query/types/path/CollectionPathTest.java b/querydsl-core/src/test/java/com/mysema/query/types/path/CollectionPathTest.java
new file mode 100644
index 000000000..64562d1ea
--- /dev/null
+++ b/querydsl-core/src/test/java/com/mysema/query/types/path/CollectionPathTest.java
@@ -0,0 +1,21 @@
+package com.mysema.query.types.path;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.mysema.query.types.PathMetadataFactory;
+
+public class CollectionPathTest {
+    
+    @Test
+    public void test(){
+        CollectionPath stringPath = new CollectionPath(
+                String.class, StringPath.class, 
+                PathMetadataFactory.forVariable("stringPath"));
+        assertEquals("stringPath", stringPath.toString());
+        assertEquals("stringPath", stringPath.any().toString());
+        assertEquals("eqIc(stringPath,X)", stringPath.any().equalsIgnoreCase("X").toString());
+    }
+
+}
diff --git a/querydsl-core/src/test/java/com/mysema/query/types/path/ListPathTest.java b/querydsl-core/src/test/java/com/mysema/query/types/path/ListPathTest.java
new file mode 100644
index 000000000..3ee34d10d
--- /dev/null
+++ b/querydsl-core/src/test/java/com/mysema/query/types/path/ListPathTest.java
@@ -0,0 +1,22 @@
+package com.mysema.query.types.path;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.mysema.query.types.PathMetadataFactory;
+
+public class ListPathTest {
+    
+    @Test
+    public void test(){
+        ListPath stringPath = new ListPath(
+                String.class, StringPath.class, 
+                PathMetadataFactory.forVariable("stringPath"));
+        assertEquals("stringPath", stringPath.toString());
+        assertEquals("stringPath", stringPath.any().toString());
+        assertEquals("eqIc(stringPath.get(0),X)", stringPath.get(0).equalsIgnoreCase("X").toString());
+        assertEquals("eqIc(stringPath,X)", stringPath.any().equalsIgnoreCase("X").toString());
+    }
+
+}
diff --git a/querydsl-core/src/test/java/com/mysema/query/types/path/SetPathTest.java b/querydsl-core/src/test/java/com/mysema/query/types/path/SetPathTest.java
new file mode 100644
index 000000000..24763e24d
--- /dev/null
+++ b/querydsl-core/src/test/java/com/mysema/query/types/path/SetPathTest.java
@@ -0,0 +1,21 @@
+package com.mysema.query.types.path;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.mysema.query.types.PathMetadataFactory;
+
+public class SetPathTest {
+    
+    @Test
+    public void test(){
+        SetPath stringPath = new SetPath(
+                String.class, StringPath.class, 
+                PathMetadataFactory.forVariable("stringPath"));
+        assertEquals("stringPath", stringPath.toString());
+        assertEquals("stringPath", stringPath.any().toString());
+        assertEquals("eqIc(stringPath,X)", stringPath.any().equalsIgnoreCase("X").toString());
+    }
+
+}
diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java
index 7b5573bb0..9a8f5ef0a 100644
--- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java
+++ b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java
@@ -43,7 +43,7 @@ public class JDOQLMethodsTest extends AbstractJDOTest {
 
     private  List getFilters(
             StringExpression str, StringExpression other, String knownString,
-            CollectionPath list, A element,
+            CollectionPath list, A element,
             MapPath map, K key, V value,
             NumberExpression number){
         return Arrays.asList(
diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java
index 58288c507..27453f085 100644
--- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java
+++ b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java
@@ -25,7 +25,7 @@ public class QStore extends EntityPathBase productsByName = this.createMap("productsByName",String.class,Product.class,QProduct.class);
 
-    public final CollectionPath products = createCollection("products",Product.class);
+    public final CollectionPath products = createCollection("products",Product.class,QProduct.class);
 
     public QProduct productsByName(String key) {
         return new QProduct(PathMetadataFactory.forMapAccess(productsByName,key));