You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2019/01/04 10:40:39 UTC

[1/3] cayenne git commit: CAY-2507 Property api to add aliases

Repository: cayenne
Updated Branches:
  refs/heads/master 008e77d1e -> 988937524


CAY-2507 Property api to add aliases


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

Branch: refs/heads/master
Commit: e996e8001658698ecd4ccc56f41aafd4e04b0924
Parents: 9ea878c
Author: Arseni Bulatski <an...@gmail.com>
Authored: Sat Dec 29 16:58:14 2018 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Wed Jan 2 16:10:45 2019 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   8 +
 .../apache/cayenne/exp/ExpressionFactory.java   |   2 +-
 .../apache/cayenne/exp/parser/ASTDbPath.java    |  13 +-
 .../apache/cayenne/exp/parser/ASTObjPath.java   |   7 +-
 .../org/apache/cayenne/exp/parser/ASTPath.java  |   6 +-
 .../cayenne/exp/property/BaseProperty.java      |  10 +-
 .../cayenne/exp/property/EntityProperty.java    |   6 +-
 .../cayenne/exp/property/ListProperty.java      |  10 +-
 .../cayenne/exp/property/MapProperty.java       |  13 +-
 .../cayenne/exp/property/PropertyFactory.java   |   4 +-
 .../cayenne/exp/property/PropertyUtils.java     |  70 +++++++
 .../exp/property/RelationshipProperty.java      |  49 ++++-
 .../cayenne/exp/property/SetProperty.java       |  10 +-
 .../java/org/apache/cayenne/map/ObjEntity.java  |  51 ++---
 .../cayenne/query/SelectQueryMetadata.java      |  74 ++++++--
 .../exp/property/EntityPropertyTest.java        |  15 +-
 .../cayenne/exp/property/ListPropertyTest.java  |  22 ++-
 .../cayenne/exp/property/MapPropertyTest.java   |  19 +-
 .../cayenne/exp/property/PropertyAliasesIT.java | 189 +++++++++++++++++++
 .../cayenne/exp/property/SetPropertyTest.java   |  13 +-
 .../apache/cayenne/query/ColumnSelectIT.java    |  27 +--
 .../apache/cayenne/query/ObjectSelectTest.java  |  20 +-
 .../cayenne/query/ObjectSelect_AggregateIT.java |  18 +-
 .../cayenne/query/ObjectSelect_RunIT.java       |   5 +-
 .../org/apache/cayenne/query/SelectQueryIT.java |  23 ++-
 25 files changed, 537 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index f2248cd..aaa4e39 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -8,6 +8,14 @@ To browse individual bug reports check out project issue tracker:
 https://issues.apache.org/jira/browse/CAY
 
 ----------------------------------
+Release: 4.2.M1
+Date:
+----------------------------------
+Changes/New Features:
+
+CAY-2507 Property api to add aliases
+
+----------------------------------
 Release: 4.1.M3
 Date:
 ----------------------------------

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
index 92f45cc..3ad5e77 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
@@ -329,7 +329,7 @@ public class ExpressionFactory {
 
 			int splitEnd = path.indexOf(Entity.PATH_SEPARATOR, split + 1);
 
-			String beforeSplit = split > 0 ? path.substring(0, split) + "." : "";
+			String beforeSplit = split > 0 ? path.substring(0, split) : "";
 			String afterSplit = splitEnd > 0 ? "." + path.substring(splitEnd + 1) : "";
 			String aliasBase = "split" + autoAliasId++ + "_";
 			String splitChunk = splitEnd > 0 ? path.substring(split + 1, splitEnd) : path.substring(split + 1);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
index f3f2f7b..870b84d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
@@ -19,12 +19,6 @@
 
 package org.apache.cayenne.exp.parser;
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.cayenne.Cayenne;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
@@ -39,6 +33,12 @@ import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.util.CayenneMapEntry;
 
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 /**
  * Path expression traversing DB relationships and attributes.
  * 
@@ -166,6 +166,7 @@ public class ASTDbPath extends ASTPath {
 	public Expression shallowCopy() {
 		ASTDbPath copy = new ASTDbPath(id);
 		copy.path = path;
+		copy.setPathAliases(pathAliases);
 		return copy;
 	}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
index 6c1604e..c536fc6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
@@ -19,9 +19,6 @@
 
 package org.apache.cayenne.exp.parser;
 
-import java.io.IOException;
-import java.util.List;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataObject;
 import org.apache.cayenne.exp.Expression;
@@ -31,6 +28,9 @@ import org.apache.cayenne.reflect.PropertyUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.util.List;
+
 public class ASTObjPath extends ASTPath {
 
 	private static final long serialVersionUID = -3574281576491705706L;
@@ -68,6 +68,7 @@ public class ASTObjPath extends ASTPath {
 	public Expression shallowCopy() {
 		ASTObjPath copy = new ASTObjPath(id);
 		copy.path = path;
+		copy.setPathAliases(pathAliases);
 		return copy;
 	}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
index 8ab1a39..f88b570 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
@@ -19,12 +19,12 @@
 
 package org.apache.cayenne.exp.parser;
 
-import java.util.Iterator;
-import java.util.Map;
-
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.util.CayenneMapEntry;
 
+import java.util.Iterator;
+import java.util.Map;
+
 /**
  * Generic path expression.
  * 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
index 1ce3836..28bc264 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
@@ -19,11 +19,6 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Supplier;
-
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.FunctionExpressionFactory;
@@ -33,6 +28,11 @@ import org.apache.cayenne.query.Orderings;
 import org.apache.cayenne.query.SortOrder;
 import org.apache.cayenne.reflect.PropertyUtils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Supplier;
+
 /**
  * Property that represents generic attribute.
  * <p>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
index 6398a22..1f087d6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
@@ -56,7 +56,11 @@ public class EntityProperty<E extends Persistent> extends BaseProperty<E> implem
      */
     @Override
     public EntityProperty<E> alias(String alias) {
-        return PropertyFactory.createEntity(alias, getExpression(), getType());
+        String substrPath = PropertyUtils.substringPath(this.getName());
+        String aliasedPath = substrPath + alias;
+        return PropertyFactory.createEntity(aliasedPath,
+                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
+                this.getType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
index 410d6db..d8021dc 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
@@ -19,11 +19,11 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.List;
-
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 
+import java.util.List;
+
 /**
  * Property that represents to-many relationship mapped on {@link List}.
  * <pre>{@code
@@ -52,7 +52,11 @@ public class ListProperty<V extends Persistent> extends CollectionProperty<V, Li
      */
     @Override
     public ListProperty<V> alias(String alias) {
-        return PropertyFactory.createList(alias, this.getExpression(), this.getEntityType());
+        String substrPath = PropertyUtils.substringPath(this.getName());
+        String aliasedPath = substrPath + alias;
+        return PropertyFactory.createList(aliasedPath,
+                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
+                this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
index 0137659..1974de4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
@@ -19,13 +19,13 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.Collection;
-import java.util.Map;
-
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 
+import java.util.Collection;
+import java.util.Map;
+
 /**
  * Property that represents to-many relationship mapped on {@link Map}.
  *
@@ -204,7 +204,12 @@ public class MapProperty<K, V extends Persistent> extends BaseProperty<Map<K, V>
      */
     @Override
     public MapProperty<K, V> alias(String alias) {
-        return PropertyFactory.createMap(alias, this.getExpression(), getKeyType(), getEntityType());
+        String substrPath = PropertyUtils.substringPath(this.getName());
+        String aliasedPath = substrPath + alias;
+        return PropertyFactory.createMap(aliasedPath,
+                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
+                this.getKeyType(),
+                this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
index c355d73..e16d936 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
@@ -19,14 +19,14 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.time.LocalDateTime;
-
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.FunctionExpressionFactory;
 
+import java.time.LocalDateTime;
+
 /**
  *
  * Factory class that produces all property types.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
new file mode 100644
index 0000000..43b41fc
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
@@ -0,0 +1,70 @@
+/*****************************************************************
+ *   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.exp.property;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTPath;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 4.2
+ */
+class PropertyUtils {
+
+    static ASTPath createPathExp(String aliasedPath, String segment, String alias, Map<String, String> aliasMap) {
+        ASTPath pathExp = new ASTObjPath(aliasedPath);
+        Map<String, String> aliases = new HashMap<>(aliasMap);
+        aliases.put(alias, segment);
+        pathExp.setPathAliases(aliases);
+
+        return pathExp;
+    }
+
+    static ASTPath createExpressionWithCopiedAliases(String name, Expression expression) {
+        if(expression instanceof ASTPath) {
+            ASTPath pathExp = new ASTObjPath(name);
+            pathExp.setPathAliases(expression.getPathAliases());
+            return pathExp;
+        }
+
+        throw new CayenneRuntimeException("Dot is used only with path expressions.");
+    }
+
+    static String substringPath(String propertyName){
+        for(int i = propertyName.length() - 1; i >= 0; i--) {
+            if(propertyName.charAt(i) == '.') {
+                return propertyName.substring(0, i + 1);
+            }
+        }
+
+        return "";
+    }
+
+    static void checkAliases(Expression expression) {
+        if(!expression.getPathAliases().isEmpty()) {
+            throw new CayenneRuntimeException("Can't use aliases with prefetch");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
index 13b9fdc..76e9d5a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
@@ -38,7 +38,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default BaseProperty<Object> dot(String property) {
-        return PropertyFactory.createBase(getName() + "." + property, null);
+        String path = getName() + "." + property;
+        return PropertyFactory.createBase(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                null);
     }
 
     /**
@@ -48,7 +51,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T> BaseProperty<T> dot(BaseProperty<T> property) {
-        return PropertyFactory.createBase(getName() + "." + property.getName(), property.getType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createBase(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getType());
     }
 
     /**
@@ -58,7 +64,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T extends Number> NumericProperty<T> dot(NumericProperty<T> property) {
-        return PropertyFactory.createNumeric(getName() + "." + property.getName(), property.getType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createNumeric(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getType());
     }
 
     /**
@@ -68,7 +77,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T extends CharSequence> StringProperty<T> dot(StringProperty<T> property) {
-        return PropertyFactory.createString(getName() + "." + property.getName(), property.getType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createString(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getType());
     }
 
     /**
@@ -78,7 +90,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T> DateProperty<T> dot(DateProperty<T> property) {
-        return PropertyFactory.createDate(getName() + "." + property.getName(), property.getType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createDate(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getType());
     }
 
     /**
@@ -88,7 +103,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T extends Persistent> EntityProperty<T> dot(EntityProperty<T> property) {
-        return PropertyFactory.createEntity(getName() + "." + property.getName(), property.getType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createEntity(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getType());
     }
 
     /**
@@ -98,7 +116,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T extends Persistent> ListProperty<T> dot(ListProperty<T> property) {
-        return PropertyFactory.createList(getName() + "." + property.getName(), property.getEntityType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createList(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getEntityType());
     }
 
     /**
@@ -108,7 +129,10 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <T extends Persistent> SetProperty<T> dot(SetProperty<T> property) {
-        return PropertyFactory.createSet(getName() + "." + property.getName(), property.getEntityType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createSet(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getEntityType());
     }
 
     /**
@@ -118,7 +142,11 @@ public interface RelationshipProperty<E> extends Property<E> {
      * @return a newly created Property object.
      */
     default <K, V extends Persistent> MapProperty<K, V> dot(MapProperty<K, V> property) {
-        return PropertyFactory.createMap(getName() + "." + property.getName(), property.getKeyType(), property.getEntityType());
+        String path = getName() + "." + property.getName();
+        return PropertyFactory.createMap(path,
+                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                property.getKeyType(),
+                property.getEntityType());
     }
 
     /**
@@ -134,6 +162,7 @@ public interface RelationshipProperty<E> extends Property<E> {
      * prefetch semantics.
      */
     default PrefetchTreeNode joint() {
+        PropertyUtils.checkAliases(getExpression());
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
     }
 
@@ -143,6 +172,7 @@ public interface RelationshipProperty<E> extends Property<E> {
      * "disjoint" prefetch semantics.
      */
     default PrefetchTreeNode disjoint() {
+        PropertyUtils.checkAliases(getExpression());
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
     }
 
@@ -152,6 +182,7 @@ public interface RelationshipProperty<E> extends Property<E> {
      * "disjoint by id" prefetch semantics.
      */
     default PrefetchTreeNode disjointById() {
+        PropertyUtils.checkAliases(getExpression());
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
index f7ded0b..908fab7 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
@@ -19,11 +19,11 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.Set;
-
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 
+import java.util.Set;
+
 /**
  * Property that represents to-many relationship mapped on {@link Set}.
  *
@@ -48,7 +48,11 @@ public class SetProperty<V extends Persistent> extends CollectionProperty<V, Set
      */
     @Override
     public SetProperty<V> alias(String alias) {
-        return PropertyFactory.createSet(alias, this.getExpression(), this.getEntityType());
+        String substrPath = PropertyUtils.substringPath(this.getName());
+        String aliasedPath = substrPath + alias;
+        return PropertyFactory.createSet(aliasedPath,
+                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
+                this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
index 74e793d..d9ddca3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
@@ -1003,15 +1003,14 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
 
         DBPathConverter transformer = new DBPathConverter();
 
-        String dbPath = transformer.toDbPath(createPathIterator(relationshipPath));
+        String dbPath = transformer.toDbPath(createPathIterator(relationshipPath, expression.getPathAliases()));
         Expression dbClone = expression.transform(transformer);
 
         return getDbEntity().translateToRelatedEntity(dbClone, dbPath);
     }
 
-    private PathComponentIterator createPathIterator(String path) {
-        return new PathComponentIterator(ObjEntity.this, path, Collections.emptyMap());
-        // TODO: do we need aliases here?
+    private PathComponentIterator createPathIterator(String path, Map<String, String> aliasMap) {
+        return new PathComponentIterator(ObjEntity.this, path, aliasMap);
     }
 
     /**
@@ -1037,31 +1036,41 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
                 PathComponent<Attribute, Relationship> component = objectPathComponents.next();
 
                 Iterator<?> dbSubpath;
-
-                if (component.getAttribute() != null) {
+                if(component.getAttribute() != null) {
                     dbSubpath = ((ObjAttribute) component.getAttribute()).getDbPathIterator();
-                } else if (component.getRelationship() != null) {
+                    buildPath(dbSubpath, component, buf);
+                } else if(component.getRelationship() != null) {
                     dbSubpath = ((ObjRelationship) component.getRelationship()).getDbRelationships().iterator();
+                    buildPath(dbSubpath, component, buf);
+                } else if(component.getAliasedPath() != null) {
+                    for(PathComponent<Attribute, Relationship> pathComponent : component.getAliasedPath()) {
+                       if(pathComponent.getRelationship() != null) {
+                           dbSubpath = ((ObjRelationship) pathComponent.getRelationship()).getDbRelationships().iterator();
+                           buildPath(dbSubpath, pathComponent, buf);
+                       }
+                    }
                 } else {
                     throw new CayenneRuntimeException("Unknown path component: %s", component);
                 }
+            }
 
-                while (dbSubpath.hasNext()) {
-                    CayenneMapEntry subComponent = (CayenneMapEntry) dbSubpath.next();
-                    if (buf.length() > 0) {
-                        buf.append(Entity.PATH_SEPARATOR);
-                    }
+            return buf.toString();
+        }
 
-                    buf.append(subComponent.getName());
-                    
-                    // use OUTER join for all components of the path is Obj path is OUTER
-                    if (component.getJoinType() == JoinType.LEFT_OUTER) {
-                        buf.append(OUTER_JOIN_INDICATOR);
-                    }
+        private void buildPath(Iterator<?> dbSubpath, PathComponent<Attribute, Relationship> component, StringBuilder buf) {
+            while (dbSubpath.hasNext()) {
+                CayenneMapEntry subComponent = (CayenneMapEntry) dbSubpath.next();
+                if (buf.length() > 0) {
+                    buf.append(Entity.PATH_SEPARATOR);
                 }
-            }
 
-            return buf.toString();
+                buf.append(subComponent.getName());
+
+                // use OUTER join for all components of the path is Obj path is OUTER
+                if (component.getJoinType() == JoinType.LEFT_OUTER) {
+                    buf.append(OUTER_JOIN_INDICATOR);
+                }
+            }
         }
 
         public Object apply(Object input) {
@@ -1077,7 +1086,7 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
             }
 
             // convert obj_path to db_path
-            String converted = toDbPath(createPathIterator((String) expression.getOperand(0)));
+            String converted = toDbPath(createPathIterator((String) expression.getOperand(0), expression.getPathAliases()));
             return ExpressionFactory.dbPathExp(converted);
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
index 13c6761..63e72f8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
@@ -18,26 +18,18 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.access.types.ValueObjectType;
 import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
-import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.TraversalHandler;
 import org.apache.cayenne.exp.parser.ASTDbPath;
 import org.apache.cayenne.exp.parser.ASTFunctionCall;
 import org.apache.cayenne.exp.parser.ASTScalar;
+import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
@@ -56,6 +48,15 @@ import org.apache.cayenne.reflect.ToManyProperty;
 import org.apache.cayenne.reflect.ToOneProperty;
 import org.apache.cayenne.util.CayenneMapEntry;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * @since 3.0
  */
@@ -63,9 +64,9 @@ class SelectQueryMetadata extends BaseQueryMetadata {
 
 	private static final long serialVersionUID = 7465922769303943945L;
 	
-	Map<String, String> pathSplitAliases;
-	boolean isSingleResultSetMapping;
-	boolean suppressingDistinct;
+	private Map<String, String> pathSplitAliases;
+	private boolean isSingleResultSetMapping;
+	private boolean suppressingDistinct;
 
 	@Override
 	void copyFromInfo(QueryMetadata info) {
@@ -154,21 +155,64 @@ class SelectQueryMetadata extends BaseQueryMetadata {
 	}
 
 	private void resolveAutoAliases(SelectQuery<?> query) {
+		resolveQualifierAliases(query);
+		resolveColumnsAliases(query);
+        resolveOrderingAliases(query);
+		resolveHavingQualifierAliases(query);
+		// TODO: include aliases in prefetches? flattened attributes?
+	}
+
+	private void resolveQualifierAliases(SelectQuery<?> query) {
 		Expression qualifier = query.getQualifier();
 		if (qualifier != null) {
 			resolveAutoAliases(qualifier);
 		}
-
-		// TODO: include aliases in prefetches? flattened attributes?
 	}
 
+	private void resolveColumnsAliases(SelectQuery<?> query) {
+        Collection<BaseProperty<?>> columns = query.getColumns();
+        if(columns != null) {
+            for(BaseProperty<?> property : columns) {
+                Expression propertyExpression = property.getExpression();
+                if(propertyExpression != null) {
+                    resolveAutoAliases(propertyExpression);
+                }
+            }
+        }
+    }
+
+    private void resolveOrderingAliases(SelectQuery<?> query) {
+        List<Ordering> orderings = query.getOrderings();
+        if(orderings != null) {
+            for(Ordering ordering : orderings) {
+                Expression sortSpec = ordering.getSortSpec();
+                if(sortSpec != null) {
+                    resolveAutoAliases(sortSpec);
+                }
+            }
+        }
+    }
+
+    private void resolveHavingQualifierAliases(SelectQuery<?> query) {
+        Expression havingQualifier = query.getHavingQualifier();
+        if(havingQualifier != null) {
+            resolveAutoAliases(havingQualifier);
+        }
+    }
+
 	private void resolveAutoAliases(Expression expression) {
 		Map<String, String> aliases = expression.getPathAliases();
 		if (!aliases.isEmpty()) {
 			if (pathSplitAliases == null) {
 				pathSplitAliases = new HashMap<>();
 			}
-
+			for(String key : aliases.keySet()) {
+				if(pathSplitAliases.containsKey(key)) {
+					if(!pathSplitAliases.get(key).equals(aliases.get(key))) {
+						throw new CayenneRuntimeException("Can't add the same alias to different path segments.");
+					}
+				}
+			}
 			pathSplitAliases.putAll(aliases);
 		}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/exp/property/EntityPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/EntityPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/EntityPropertyTest.java
index 8b9ba0e..046e37a 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/EntityPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/EntityPropertyTest.java
@@ -24,7 +24,7 @@ import org.apache.cayenne.testdo.testmap.Artist;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 /**
  * @since 4.2
@@ -32,21 +32,26 @@ import static org.junit.Assert.*;
 public class EntityPropertyTest {
 
     private EntityProperty<Artist> property;
+    private EntityProperty<Artist> property1;
 
     @Before
     public void createProperty() {
         property = new EntityProperty<>("path", null, Artist.class);
+        property1 = new EntityProperty<>("path.artist", null, Artist.class);
     }
 
     @Test
     public void alias() {
         assertEquals("path", property.getName());
-        assertNull(property.getAlias());
-
         property = property.alias("alias");
-
         assertEquals("alias", property.getName());
-        assertEquals("alias", property.getAlias());
+        assertEquals(1, property.getExpression().getPathAliases().size());
+
+        assertEquals("path.artist", property1.getName());
+        property1 = property1.alias("a");
+        assertEquals("path.a", property1.getName());
+        assertEquals(1, property1.getExpression().getPathAliases().size());
+        assertEquals("artist", property1.getExpression().getPathAliases().get("a"));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
index fb775af..df87539 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
@@ -19,17 +19,16 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
 
 /**
  * @since 4.2
@@ -37,22 +36,27 @@ import static org.junit.Assert.*;
 public class ListPropertyTest {
 
     private ListProperty<Artist> property;
+    private ListProperty<Artist> property1;
 
     @Before
     public void createProperty() {
         property = new ListProperty<>("path", null, Artist.class);
+        property1 = new ListProperty<>("path.artist", null, Artist.class);
     }
 
 
     @Test
     public void alias() {
         assertEquals("path", property.getName());
-        assertNull(property.getAlias());
-
         property = property.alias("alias");
-
         assertEquals("alias", property.getName());
-        assertEquals("alias", property.getAlias());
+        assertEquals(1, property.getExpression().getPathAliases().size());
+
+        assertEquals("path.artist", property1.getName());
+        property1 = property1.alias("a");
+        assertEquals("path.a", property1.getName());
+        assertEquals(1, property1.getExpression().getPathAliases().size());
+        assertEquals("artist", property1.getExpression().getPathAliases().get("a"));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
index bc4ee9e..5545942 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
@@ -19,15 +19,15 @@
 
 package org.apache.cayenne.exp.property;
 
-import java.util.Arrays;
-
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
 
 /**
  * @since 4.2
@@ -35,10 +35,12 @@ import static org.junit.Assert.*;
 public class MapPropertyTest {
 
     private MapProperty<Integer, Artist> property;
+    private MapProperty<Integer, Artist> property1;
 
     @Before
     public void createProperty() {
         property = new MapProperty<>("path", null, Integer.class, Artist.class);
+        property1 = new MapProperty<>("path.artist", null, Integer.class, Artist.class);
     }
 
     @Test
@@ -132,12 +134,15 @@ public class MapPropertyTest {
     @Test
     public void alias() {
         assertEquals("path", property.getName());
-        assertNull(property.getAlias());
-
         property = property.alias("alias");
-
         assertEquals("alias", property.getName());
-        assertEquals("alias", property.getAlias());
+        assertEquals(1, property.getExpression().getPathAliases().size());
+
+        assertEquals("path.artist", property1.getName());
+        property1 = property1.alias("a");
+        assertEquals("path.a", property1.getName());
+        assertEquals(1, property1.getExpression().getPathAliases().size());
+        assertEquals("artist", property1.getExpression().getPathAliases().get("a"));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
new file mode 100644
index 0000000..5dbfe14
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
@@ -0,0 +1,189 @@
+/*****************************************************************
+ *   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.exp.property;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTPath;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Gallery;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @since 4.2
+ */
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class PropertyAliasesIT extends ServerCase {
+
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Before
+    public void createArtistsDataSet() throws Exception {
+        TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME", "DATE_OF_BIRTH");
+
+        long dateBase = System.currentTimeMillis();
+        for (int i = 1; i <= 20; i++) {
+            tArtist.insert(i, "artist" + i, new java.sql.Date(dateBase + 10000 * i));
+        }
+
+        TableHelper tGallery = new TableHelper(dbHelper, "GALLERY");
+        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
+        tGallery.insert(1, "tate modern");
+
+        TableHelper tGallery1 = new TableHelper(dbHelper, "GALLERY");
+        tGallery1.setColumns("GALLERY_ID", "GALLERY_NAME");
+        tGallery1.insert(2, "test gallery");
+
+        TableHelper tPaintings = new TableHelper(dbHelper, "PAINTING");
+        tPaintings.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "GALLERY_ID");
+        for (int i = 1; i <= 20; i++) {
+            tPaintings.insert(i, "painting" + i,
+                    i % 2 == 0 ? 4 : i % 5 + 1,
+                    i % 2 == 0 ? 2 : 1);
+        }
+    }
+
+    @Test
+    public void testBeginAlias() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, artists.size());
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testTheSameAliases() {
+        List<Object[]> results = ObjectSelect.columnQuery(Artist.class,
+                Artist.ARTIST_NAME,
+                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE),
+                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE))
+                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, results.size());
+        assertEquals("artist4", results.get(0)[0]);
+        assertEquals("painting2", results.get(0)[1]);
+        assertEquals("painting4", results.get(0)[2]);
+    }
+
+    @Test
+    public void testMiddleAlias() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, artists.size());
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testEntityPropertyAliases() {
+        Artist artist = Cayenne.objectForPK(context, Artist.class, 1);
+
+        SelectQuery<Painting> query = SelectQuery.query(Painting.class);
+        Expression expression = Painting.TO_ARTIST.alias("p1").eq(artist);
+        query.setQualifier(expression);
+        List<Painting> paintings = query.select(context);
+        assertEquals(2, paintings.size());
+        assertEquals("painting5", paintings.get(0).getPaintingTitle());
+    }
+
+    @Test
+    public void testAliases() {
+        SelectQuery<Artist> query1 = new SelectQuery<>(Artist.class);
+        Expression expression = ExpressionFactory.and(
+                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"),
+                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4")
+        );
+        query1.setQualifier(expression);
+        List<Artist> artists = query1.select(context);
+        assertEquals(1, artists.size());
+        assertNotNull(artists.get(0));
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testAliasForPath() {
+        ASTPath astPath = new ASTObjPath("a.galleryName");
+        astPath.setPathAliases(Collections.singletonMap("a", "paintingArray.toGallery"));
+        ASTEqual astEqual = new ASTEqual(astPath, "tate modern");
+        List<Object[]> artists = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, PropertyFactory.createBase(astPath, String.class))
+                .where(astEqual)
+                .orderBy(Artist.ARTIST_NAME.asc())
+                .select(context);
+        assertEquals(5, artists.size());
+        assertEquals("artist1", artists.get(0)[0]);
+    }
+
+    @Test
+    public void testAggregationWithAliases() {
+        List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
+                .having(Artist.PAINTING_ARRAY.alias("p1").count().lt(5L))
+                .select(context);
+        assertEquals(4, artistAndPaintingCount.size());
+        assertTrue((Long)artistAndPaintingCount.get(0)[1] < 5);
+    }
+
+    @Test
+    public void testOrderWithAlias() {
+        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class)
+                .orderBy(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.ESTIMATED_PRICE).asc())
+                .prefetch(Artist.PAINTING_ARRAY.disjoint());
+        List<Artist> artists = query.select(context);
+        assertEquals(5, artists.size());
+        assertEquals(2, artists.get(0).getPaintingArray().size());
+    }
+
+    @Test(expected = CayenneRuntimeException.class)
+    public void testPrefetchWithAliases() {
+        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class);
+        query.prefetch(Artist.PAINTING_ARRAY.alias("p1").disjoint());
+        query.select(context);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/exp/property/SetPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/SetPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/SetPropertyTest.java
index 2cd258f..efba282 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/SetPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/SetPropertyTest.java
@@ -33,21 +33,26 @@ import static org.junit.Assert.*;
 public class SetPropertyTest {
 
     private SetProperty<Artist> property;
+    private SetProperty<Artist> property1;
 
     @Before
     public void createProperty() {
         property = new SetProperty<>("path", null, Artist.class);
+        property1 = new SetProperty<>("path.artist", null, Artist.class);
     }
 
     @Test
     public void alias() {
         assertEquals("path", property.getName());
-        assertNull(property.getAlias());
-
         property = property.alias("alias");
-
         assertEquals("alias", property.getName());
-        assertEquals("alias", property.getAlias());
+        assertEquals(1, property.getExpression().getPathAliases().size());
+
+        assertEquals("path.artist", property1.getName());
+        property1 = property1.alias("a");
+        assertEquals("path.a", property1.getName());
+        assertEquals(1, property1.getExpression().getPathAliases().size());
+        assertEquals("artist", property1.getExpression().getPathAliases().get("a"));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
index 04e45b5..4d2ebab 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
@@ -19,15 +19,6 @@
 
 package org.apache.cayenne.query;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.Fault;
 import org.apache.cayenne.ObjectContext;
@@ -36,8 +27,6 @@ import org.apache.cayenne.ResultBatchIterator;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.FunctionExpressionFactory;
 import org.apache.cayenne.exp.property.EntityProperty;
 import org.apache.cayenne.exp.property.NumericProperty;
 import org.apache.cayenne.exp.property.PropertyFactory;
@@ -57,7 +46,21 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * @since 4.0

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
index dd9e1f2..ae06952 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
@@ -18,6 +18,16 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -25,16 +35,6 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.junit.Test;
-
 public class ObjectSelectTest {
 
 	@Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
index e88c7cd..b5910bc 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
@@ -19,15 +19,9 @@
 
 package org.apache.cayenne.query;
 
-import java.sql.Types;
-import java.text.DateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.FunctionExpressionFactory;
 import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.property.NumericProperty;
 import org.apache.cayenne.exp.property.PropertyFactory;
@@ -42,7 +36,13 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.apache.cayenne.exp.FunctionExpressionFactory.*;
+import java.sql.Types;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -121,7 +121,7 @@ public class ObjectSelect_AggregateIT extends ServerCase {
     @Test
     @Ignore("Not all databases support AVG(DATE) aggregation")
     public void testAvg() throws Exception {
-        BaseProperty<Date> avgProp = PropertyFactory.createBase(avgExp(Artist.DATE_OF_BIRTH.getExpression()), Date.class);
+        BaseProperty<Date> avgProp = PropertyFactory.createBase(FunctionExpressionFactory.avgExp(Artist.DATE_OF_BIRTH.getExpression()), Date.class);
 
         Date avg = ObjectSelect.query(Artist.class)
                 .column(avgProp)

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
index c353e1c..df5632f 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
-import java.util.List;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ResultBatchIterator;
@@ -35,6 +33,8 @@ import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -195,5 +195,4 @@ public class ObjectSelect_RunIT extends ServerCase {
 		assertNotNull(a);
 		assertEquals("artist1", a.getArtistName());
 	}
-
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e996e800/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
index 1bd6d1b..2352612 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
@@ -19,18 +19,6 @@
 
 package org.apache.cayenne.query;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.sql.ResultSet;
-import java.sql.Types;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.cayenne.Cayenne;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
@@ -58,6 +46,17 @@ import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
 @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
 public class SelectQueryIT extends ServerCase {
 


[3/3] cayenne git commit: Merge PR #357

Posted by nt...@apache.org.
Merge PR #357


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

Branch: refs/heads/master
Commit: 988937524528f588464df42a4cbd1482452d9643
Parents: 008e77d fa1efbc
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Jan 4 13:40:23 2019 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Jan 4 13:40:23 2019 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |   1 +
 .../apache/cayenne/exp/ExpressionFactory.java   |   2 +-
 .../apache/cayenne/exp/parser/ASTDbPath.java    |   1 +
 .../apache/cayenne/exp/parser/ASTObjPath.java   |   1 +
 .../cayenne/exp/property/EntityProperty.java    |   4 +-
 .../cayenne/exp/property/ListProperty.java      |   4 +-
 .../cayenne/exp/property/MapProperty.java       |   4 +-
 .../cayenne/exp/property/PropertyUtils.java     |  48 +++++
 .../exp/property/RelationshipProperty.java      |  56 +++++-
 .../cayenne/exp/property/SetProperty.java       |   4 +-
 .../java/org/apache/cayenne/map/ObjEntity.java  |  51 +++--
 .../cayenne/query/SelectQueryMetadata.java      |  60 +++++-
 .../exp/property/EntityPropertyTest.java        |  15 +-
 .../cayenne/exp/property/ListPropertyTest.java  |  14 +-
 .../cayenne/exp/property/MapPropertyTest.java   |  15 +-
 .../cayenne/exp/property/PathAliasesIT.java     | 197 +++++++++++++++++++
 .../cayenne/exp/property/SetPropertyTest.java   |  13 +-
 .../cayenne/query/ObjectSelect_AggregateIT.java |   4 +-
 .../cayenne/query/ObjectSelect_RunIT.java       |   1 -
 .../org/apache/cayenne/query/SelectQueryIT.java |   1 -
 20 files changed, 431 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/98893752/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --cc RELEASE-NOTES.txt
index 139e6e1,aaa4e39..23d20e5
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@@ -13,11 -13,7 +13,12 @@@ Date
  ----------------------------------
  Changes/New Features:
  
 -CAY-2507 Property api to add aliases
 +CAY-2467 New type-aware Property API
++CAY-2507 Property API to use path aliases
 +
 +Bug Fixes:
 +
 +CAY-2332 Property API: unable to use eq() and in() methods for toMany relationships
  
  ----------------------------------
  Release: 4.1.M3


[2/3] cayenne git commit: Cleanup

Posted by nt...@apache.org.
Cleanup


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

Branch: refs/heads/master
Commit: fa1efbce67608a5267660d606cc9fd1169c363c5
Parents: e996e80
Author: Arseni Bulatski <an...@gmail.com>
Authored: Fri Jan 4 11:58:19 2019 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Fri Jan 4 12:08:52 2019 +0300

----------------------------------------------------------------------
 .../apache/cayenne/exp/parser/ASTDbPath.java    |  12 +-
 .../apache/cayenne/exp/parser/ASTObjPath.java   |   6 +-
 .../org/apache/cayenne/exp/parser/ASTPath.java  |   6 +-
 .../cayenne/exp/property/BaseProperty.java      |  10 +-
 .../cayenne/exp/property/EntityProperty.java    |   8 +-
 .../cayenne/exp/property/ListProperty.java      |  12 +-
 .../cayenne/exp/property/MapProperty.java       |  15 +-
 .../cayenne/exp/property/PropertyFactory.java   |   4 +-
 .../cayenne/exp/property/PropertyUtils.java     |  50 ++---
 .../exp/property/RelationshipProperty.java      |  31 +--
 .../cayenne/exp/property/SetProperty.java       |  12 +-
 .../cayenne/query/SelectQueryMetadata.java      |  30 +--
 .../cayenne/exp/property/ListPropertyTest.java  |   8 +-
 .../cayenne/exp/property/MapPropertyTest.java   |   4 +-
 .../cayenne/exp/property/PathAliasesIT.java     | 197 +++++++++++++++++++
 .../cayenne/exp/property/PropertyAliasesIT.java | 189 ------------------
 .../apache/cayenne/query/ColumnSelectIT.java    |  25 +--
 .../apache/cayenne/query/ObjectSelectTest.java  |  20 +-
 .../cayenne/query/ObjectSelect_AggregateIT.java |  22 +--
 .../cayenne/query/ObjectSelect_RunIT.java       |   4 +-
 .../org/apache/cayenne/query/SelectQueryIT.java |  22 +--
 21 files changed, 334 insertions(+), 353 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
index 870b84d..6503bf2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
@@ -19,6 +19,12 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.cayenne.Cayenne;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
@@ -33,12 +39,6 @@ import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.util.CayenneMapEntry;
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
 /**
  * Path expression traversing DB relationships and attributes.
  * 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
index c536fc6..8535b28 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
@@ -19,6 +19,9 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.io.IOException;
+import java.util.List;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataObject;
 import org.apache.cayenne.exp.Expression;
@@ -28,9 +31,6 @@ import org.apache.cayenne.reflect.PropertyUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.List;
-
 public class ASTObjPath extends ASTPath {
 
 	private static final long serialVersionUID = -3574281576491705706L;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
index f88b570..8ab1a39 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
@@ -19,12 +19,12 @@
 
 package org.apache.cayenne.exp.parser;
 
-import org.apache.cayenne.map.Entity;
-import org.apache.cayenne.util.CayenneMapEntry;
-
 import java.util.Iterator;
 import java.util.Map;
 
+import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.util.CayenneMapEntry;
+
 /**
  * Generic path expression.
  * 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
index 28bc264..1ce3836 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/BaseProperty.java
@@ -19,6 +19,11 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Supplier;
+
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.FunctionExpressionFactory;
@@ -28,11 +33,6 @@ import org.apache.cayenne.query.Orderings;
 import org.apache.cayenne.query.SortOrder;
 import org.apache.cayenne.reflect.PropertyUtils;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Supplier;
-
 /**
  * Property that represents generic attribute.
  * <p>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
index 1f087d6..41c225f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
@@ -21,6 +21,7 @@ package org.apache.cayenne.exp.property;
 
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTPath;
 
 /**
  * Property that represents to-one relationships.
@@ -56,11 +57,8 @@ public class EntityProperty<E extends Persistent> extends BaseProperty<E> implem
      */
     @Override
     public EntityProperty<E> alias(String alias) {
-        String substrPath = PropertyUtils.substringPath(this.getName());
-        String aliasedPath = substrPath + alias;
-        return PropertyFactory.createEntity(aliasedPath,
-                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
-                this.getType());
+        ASTPath exp = PropertyUtils.createPathExp(this.getName(), alias, getExpression().getPathAliases());
+        return PropertyFactory.createEntity(exp.getPath(), exp, this.getType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
index d8021dc..ded0084 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/ListProperty.java
@@ -19,10 +19,11 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.List;
+
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
-
-import java.util.List;
+import org.apache.cayenne.exp.parser.ASTPath;
 
 /**
  * Property that represents to-many relationship mapped on {@link List}.
@@ -52,11 +53,8 @@ public class ListProperty<V extends Persistent> extends CollectionProperty<V, Li
      */
     @Override
     public ListProperty<V> alias(String alias) {
-        String substrPath = PropertyUtils.substringPath(this.getName());
-        String aliasedPath = substrPath + alias;
-        return PropertyFactory.createList(aliasedPath,
-                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
-                this.getEntityType());
+        ASTPath exp = PropertyUtils.createPathExp(this.getName(), alias, getExpression().getPathAliases());
+        return PropertyFactory.createList(exp.getPath(), exp, this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
index 1974de4..b9b24b3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/MapProperty.java
@@ -19,12 +19,13 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.Collection;
+import java.util.Map;
+
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
-
-import java.util.Collection;
-import java.util.Map;
+import org.apache.cayenne.exp.parser.ASTPath;
 
 /**
  * Property that represents to-many relationship mapped on {@link Map}.
@@ -204,12 +205,8 @@ public class MapProperty<K, V extends Persistent> extends BaseProperty<Map<K, V>
      */
     @Override
     public MapProperty<K, V> alias(String alias) {
-        String substrPath = PropertyUtils.substringPath(this.getName());
-        String aliasedPath = substrPath + alias;
-        return PropertyFactory.createMap(aliasedPath,
-                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
-                this.getKeyType(),
-                this.getEntityType());
+        ASTPath exp = PropertyUtils.createPathExp(this.getName(), alias, getExpression().getPathAliases());
+        return PropertyFactory.createMap(exp.getPath(), exp, this.getKeyType(), this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
index e16d936..c355d73 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyFactory.java
@@ -19,14 +19,14 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.time.LocalDateTime;
+
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.FunctionExpressionFactory;
 
-import java.time.LocalDateTime;
-
 /**
  *
  * Factory class that produces all property types.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
index 43b41fc..098fc40 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/PropertyUtils.java
@@ -19,52 +19,30 @@
 
 package org.apache.cayenne.exp.property;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.parser.ASTObjPath;
-import org.apache.cayenne.exp.parser.ASTPath;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTPath;
+
 /**
  * @since 4.2
  */
 class PropertyUtils {
 
-    static ASTPath createPathExp(String aliasedPath, String segment, String alias, Map<String, String> aliasMap) {
-        ASTPath pathExp = new ASTObjPath(aliasedPath);
-        Map<String, String> aliases = new HashMap<>(aliasMap);
-        aliases.put(alias, segment);
-        pathExp.setPathAliases(aliases);
+    static ASTPath createPathExp(String path, String alias, Map<String, String> aliasMap) {
+        int index = path.lastIndexOf(".");
+        String aliasedPath = index != -1 ? path.substring(0, index + 1) + alias : alias;
+        String segmentPath = path.substring(index != -1 ? index + 1 : 0);
 
-        return pathExp;
+        Map<String, String> pathAliases = new HashMap<>(aliasMap);
+        pathAliases.put(alias, segmentPath);
+        return buildExp(aliasedPath, pathAliases);
     }
 
-    static ASTPath createExpressionWithCopiedAliases(String name, Expression expression) {
-        if(expression instanceof ASTPath) {
-            ASTPath pathExp = new ASTObjPath(name);
-            pathExp.setPathAliases(expression.getPathAliases());
-            return pathExp;
-        }
-
-        throw new CayenneRuntimeException("Dot is used only with path expressions.");
-    }
-
-    static String substringPath(String propertyName){
-        for(int i = propertyName.length() - 1; i >= 0; i--) {
-            if(propertyName.charAt(i) == '.') {
-                return propertyName.substring(0, i + 1);
-            }
-        }
-
-        return "";
-    }
-
-    static void checkAliases(Expression expression) {
-        if(!expression.getPathAliases().isEmpty()) {
-            throw new CayenneRuntimeException("Can't use aliases with prefetch");
-        }
+    static ASTPath buildExp(String path, Map<String, String> pathAliases) {
+        ASTPath pathExp = new ASTObjPath(path);
+        pathExp.setPathAliases(pathAliases);
+        return pathExp;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
index 76e9d5a..a4e4ba5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/RelationshipProperty.java
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.exp.property;
 
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.query.PrefetchTreeNode;
 
@@ -40,7 +41,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default BaseProperty<Object> dot(String property) {
         String path = getName() + "." + property;
         return PropertyFactory.createBase(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 null);
     }
 
@@ -53,7 +54,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T> BaseProperty<T> dot(BaseProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createBase(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getType());
     }
 
@@ -66,7 +67,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T extends Number> NumericProperty<T> dot(NumericProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createNumeric(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getType());
     }
 
@@ -79,7 +80,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T extends CharSequence> StringProperty<T> dot(StringProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createString(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getType());
     }
 
@@ -92,7 +93,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T> DateProperty<T> dot(DateProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createDate(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getType());
     }
 
@@ -105,7 +106,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T extends Persistent> EntityProperty<T> dot(EntityProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createEntity(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getType());
     }
 
@@ -118,7 +119,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T extends Persistent> ListProperty<T> dot(ListProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createList(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getEntityType());
     }
 
@@ -131,7 +132,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <T extends Persistent> SetProperty<T> dot(SetProperty<T> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createSet(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getEntityType());
     }
 
@@ -144,7 +145,7 @@ public interface RelationshipProperty<E> extends Property<E> {
     default <K, V extends Persistent> MapProperty<K, V> dot(MapProperty<K, V> property) {
         String path = getName() + "." + property.getName();
         return PropertyFactory.createMap(path,
-                PropertyUtils.createExpressionWithCopiedAliases(path, getExpression()),
+                PropertyUtils.buildExp(path, getExpression().getPathAliases()),
                 property.getKeyType(),
                 property.getEntityType());
     }
@@ -162,7 +163,9 @@ public interface RelationshipProperty<E> extends Property<E> {
      * prefetch semantics.
      */
     default PrefetchTreeNode joint() {
-        PropertyUtils.checkAliases(getExpression());
+        if(!getExpression().getPathAliases().isEmpty()) {
+            throw new CayenneRuntimeException("Can't use aliases with prefetch");
+        }
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
     }
 
@@ -172,7 +175,9 @@ public interface RelationshipProperty<E> extends Property<E> {
      * "disjoint" prefetch semantics.
      */
     default PrefetchTreeNode disjoint() {
-        PropertyUtils.checkAliases(getExpression());
+        if(!getExpression().getPathAliases().isEmpty()) {
+            throw new CayenneRuntimeException("Can't use aliases with prefetch");
+        }
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
     }
 
@@ -182,7 +187,9 @@ public interface RelationshipProperty<E> extends Property<E> {
      * "disjoint by id" prefetch semantics.
      */
     default PrefetchTreeNode disjointById() {
-        PropertyUtils.checkAliases(getExpression());
+        if(!getExpression().getPathAliases().isEmpty()) {
+            throw new CayenneRuntimeException("Can't use aliases with prefetch");
+        }
         return PrefetchTreeNode.withPath(getName(), PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
index 908fab7..12b1fd2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/property/SetProperty.java
@@ -19,10 +19,11 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.Set;
+
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
-
-import java.util.Set;
+import org.apache.cayenne.exp.parser.ASTPath;
 
 /**
  * Property that represents to-many relationship mapped on {@link Set}.
@@ -48,11 +49,8 @@ public class SetProperty<V extends Persistent> extends CollectionProperty<V, Set
      */
     @Override
     public SetProperty<V> alias(String alias) {
-        String substrPath = PropertyUtils.substringPath(this.getName());
-        String aliasedPath = substrPath + alias;
-        return PropertyFactory.createSet(aliasedPath,
-                PropertyUtils.createPathExp(aliasedPath, this.getName().substring(substrPath.length()), alias, getExpression().getPathAliases()),
-                this.getEntityType());
+        ASTPath exp = PropertyUtils.createPathExp(this.getName(), alias, getExpression().getPathAliases());
+        return PropertyFactory.createSet(exp.getPath(), exp, this.getEntityType());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
index 63e72f8..8a9e7d9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java
@@ -18,6 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
@@ -48,15 +57,6 @@ import org.apache.cayenne.reflect.ToManyProperty;
 import org.apache.cayenne.reflect.ToOneProperty;
 import org.apache.cayenne.util.CayenneMapEntry;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @since 3.0
  */
@@ -206,14 +206,16 @@ class SelectQueryMetadata extends BaseQueryMetadata {
 			if (pathSplitAliases == null) {
 				pathSplitAliases = new HashMap<>();
 			}
-			for(String key : aliases.keySet()) {
-				if(pathSplitAliases.containsKey(key)) {
-					if(!pathSplitAliases.get(key).equals(aliases.get(key))) {
+
+			for(Map.Entry<String, String> entry : aliases.entrySet()) {
+				pathSplitAliases.compute(entry.getKey(), (key, value) -> {
+					if(value != null && !value.equals(entry.getValue())){
 						throw new CayenneRuntimeException("Can't add the same alias to different path segments.");
+					} else {
+						return entry.getValue();
 					}
-				}
+				});
 			}
-			pathSplitAliases.putAll(aliases);
 		}
 
 		int len = expression.getOperandCount();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
index df87539..c8df661 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/ListPropertyTest.java
@@ -19,16 +19,16 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.Arrays;
+import java.util.Collection;
+
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.Collection;
-
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 
 /**
  * @since 4.2

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
index 5545942..0a866ad 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/MapPropertyTest.java
@@ -19,14 +19,14 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.Arrays;
+
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
-
 import static org.junit.Assert.assertEquals;
 
 /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
new file mode 100644
index 0000000..45fdee7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
@@ -0,0 +1,197 @@
+/*****************************************************************
+ *   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.exp.property;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTPath;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Gallery;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @since 4.2
+ */
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class PathAliasesIT extends ServerCase {
+
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Before
+    public void createArtistsDataSet() throws Exception {
+        TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME", "DATE_OF_BIRTH");
+
+        long dateBase = System.currentTimeMillis();
+        for (int i = 1; i <= 20; i++) {
+            tArtist.insert(i, "artist" + i, new java.sql.Date(dateBase + 10000 * i));
+        }
+
+        TableHelper tGallery = new TableHelper(dbHelper, "GALLERY");
+        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
+        tGallery.insert(1, "tate modern");
+
+        TableHelper tGallery1 = new TableHelper(dbHelper, "GALLERY");
+        tGallery1.setColumns("GALLERY_ID", "GALLERY_NAME");
+        tGallery1.insert(2, "test gallery");
+
+        TableHelper tPaintings = new TableHelper(dbHelper, "PAINTING");
+        tPaintings.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "GALLERY_ID");
+        for (int i = 1; i <= 20; i++) {
+            tPaintings.insert(i, "painting" + i,
+                    i % 2 == 0 ? 4 : i % 5 + 1,
+                    i % 2 == 0 ? 2 : 1);
+        }
+    }
+
+    @Test
+    public void testBeginAlias() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, artists.size());
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testTheSameAliases() {
+        List<Object[]> results = ObjectSelect.columnQuery(Artist.class,
+                Artist.ARTIST_NAME,
+                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE),
+                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE))
+                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, results.size());
+        assertEquals("artist4", results.get(0)[0]);
+        assertEquals("painting2", results.get(0)[1]);
+        assertEquals("painting4", results.get(0)[2]);
+    }
+
+    @Test
+    public void testMiddleAlias() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
+                .and(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
+                .select(context);
+        assertEquals(1, artists.size());
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testEntityPropertyAliases() {
+        Artist artist = Cayenne.objectForPK(context, Artist.class, 1);
+
+        SelectQuery<Painting> query = SelectQuery.query(Painting.class);
+        Expression expression = Painting.TO_ARTIST.alias("p1").eq(artist);
+        query.setQualifier(expression);
+        List<Painting> paintings = query.select(context);
+        assertEquals(2, paintings.size());
+        assertEquals("painting5", paintings.get(0).getPaintingTitle());
+    }
+
+    @Test
+    public void testAliases() {
+        SelectQuery<Artist> query1 = new SelectQuery<>(Artist.class);
+        Expression expression = ExpressionFactory.and(
+                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"),
+                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4")
+        );
+        query1.setQualifier(expression);
+        List<Artist> artists = query1.select(context);
+        assertEquals(1, artists.size());
+        assertNotNull(artists.get(0));
+        assertEquals("artist4", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void testAliasForPath() {
+        ASTPath astPath = new ASTObjPath("a.galleryName");
+        astPath.setPathAliases(Collections.singletonMap("a", "paintingArray.toGallery"));
+        ASTEqual astEqual = new ASTEqual(astPath, "tate modern");
+        List<Object[]> artists = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, PropertyFactory.createBase(astPath, String.class))
+                .where(astEqual)
+                .orderBy(Artist.ARTIST_NAME.asc())
+                .select(context);
+        assertEquals(5, artists.size());
+        assertEquals("artist1", artists.get(0)[0]);
+    }
+
+    @Test
+    public void testAggregationWithAliases() {
+        List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
+                .having(Artist.PAINTING_ARRAY.alias("p1").count().lt(5L))
+                .select(context);
+        assertEquals(4, artistAndPaintingCount.size());
+        assertTrue((Long)artistAndPaintingCount.get(0)[1] < 5);
+    }
+
+    @Test
+    public void testOrderWithAlias() {
+        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class)
+                .orderBy(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.ESTIMATED_PRICE).asc())
+                .prefetch(Artist.PAINTING_ARRAY.disjoint());
+        List<Artist> artists = query.select(context);
+        assertEquals(5, artists.size());
+        assertEquals(2, artists.get(0).getPaintingArray().size());
+    }
+
+    @Test(expected = CayenneRuntimeException.class)
+    public void testPrefetchWithAliases() {
+        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class);
+        query.prefetch(Artist.PAINTING_ARRAY.alias("p1").disjoint());
+        query.select(context);
+    }
+
+    @Test(expected = CayenneRuntimeException.class)
+    public void testTheSameAliasesToDifferentProperties() {
+        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class);
+        query.where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("p1"));
+        query.and(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).alias("p1").dot(Gallery.GALLERY_NAME).eq("g1"));
+        query.select(context);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
deleted file mode 100644
index 5dbfe14..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PropertyAliasesIT.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.exp.property;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.exp.parser.ASTEqual;
-import org.apache.cayenne.exp.parser.ASTObjPath;
-import org.apache.cayenne.exp.parser.ASTPath;
-import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Gallery;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.unit.di.server.CayenneProjects;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.List;
-
-import static junit.framework.TestCase.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * @since 4.2
- */
-@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
-public class PropertyAliasesIT extends ServerCase {
-
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Before
-    public void createArtistsDataSet() throws Exception {
-        TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME", "DATE_OF_BIRTH");
-
-        long dateBase = System.currentTimeMillis();
-        for (int i = 1; i <= 20; i++) {
-            tArtist.insert(i, "artist" + i, new java.sql.Date(dateBase + 10000 * i));
-        }
-
-        TableHelper tGallery = new TableHelper(dbHelper, "GALLERY");
-        tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
-        tGallery.insert(1, "tate modern");
-
-        TableHelper tGallery1 = new TableHelper(dbHelper, "GALLERY");
-        tGallery1.setColumns("GALLERY_ID", "GALLERY_NAME");
-        tGallery1.insert(2, "test gallery");
-
-        TableHelper tPaintings = new TableHelper(dbHelper, "PAINTING");
-        tPaintings.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "GALLERY_ID");
-        for (int i = 1; i <= 20; i++) {
-            tPaintings.insert(i, "painting" + i,
-                    i % 2 == 0 ? 4 : i % 5 + 1,
-                    i % 2 == 0 ? 2 : 1);
-        }
-    }
-
-    @Test
-    public void testBeginAlias() {
-        List<Artist> artists = ObjectSelect.query(Artist.class)
-                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
-                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
-                .select(context);
-        assertEquals(1, artists.size());
-        assertEquals("artist4", artists.get(0).getArtistName());
-    }
-
-    @Test
-    public void testTheSameAliases() {
-        List<Object[]> results = ObjectSelect.columnQuery(Artist.class,
-                Artist.ARTIST_NAME,
-                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE),
-                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE))
-                .where(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
-                .and(Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
-                .select(context);
-        assertEquals(1, results.size());
-        assertEquals("artist4", results.get(0)[0]);
-        assertEquals("painting2", results.get(0)[1]);
-        assertEquals("painting4", results.get(0)[2]);
-    }
-
-    @Test
-    public void testMiddleAlias() {
-        List<Artist> artists = ObjectSelect.query(Artist.class)
-                .where(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"))
-                .and(Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.PAINTING_ARRAY).alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4"))
-                .select(context);
-        assertEquals(1, artists.size());
-        assertEquals("artist4", artists.get(0).getArtistName());
-    }
-
-    @Test
-    public void testEntityPropertyAliases() {
-        Artist artist = Cayenne.objectForPK(context, Artist.class, 1);
-
-        SelectQuery<Painting> query = SelectQuery.query(Painting.class);
-        Expression expression = Painting.TO_ARTIST.alias("p1").eq(artist);
-        query.setQualifier(expression);
-        List<Painting> paintings = query.select(context);
-        assertEquals(2, paintings.size());
-        assertEquals("painting5", paintings.get(0).getPaintingTitle());
-    }
-
-    @Test
-    public void testAliases() {
-        SelectQuery<Artist> query1 = new SelectQuery<>(Artist.class);
-        Expression expression = ExpressionFactory.and(
-                Artist.PAINTING_ARRAY.alias("p1").dot(Painting.PAINTING_TITLE).eq("painting2"),
-                Artist.PAINTING_ARRAY.alias("p2").dot(Painting.PAINTING_TITLE).eq("painting4")
-        );
-        query1.setQualifier(expression);
-        List<Artist> artists = query1.select(context);
-        assertEquals(1, artists.size());
-        assertNotNull(artists.get(0));
-        assertEquals("artist4", artists.get(0).getArtistName());
-    }
-
-    @Test
-    public void testAliasForPath() {
-        ASTPath astPath = new ASTObjPath("a.galleryName");
-        astPath.setPathAliases(Collections.singletonMap("a", "paintingArray.toGallery"));
-        ASTEqual astEqual = new ASTEqual(astPath, "tate modern");
-        List<Object[]> artists = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, PropertyFactory.createBase(astPath, String.class))
-                .where(astEqual)
-                .orderBy(Artist.ARTIST_NAME.asc())
-                .select(context);
-        assertEquals(5, artists.size());
-        assertEquals("artist1", artists.get(0)[0]);
-    }
-
-    @Test
-    public void testAggregationWithAliases() {
-        List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
-                .having(Artist.PAINTING_ARRAY.alias("p1").count().lt(5L))
-                .select(context);
-        assertEquals(4, artistAndPaintingCount.size());
-        assertTrue((Long)artistAndPaintingCount.get(0)[1] < 5);
-    }
-
-    @Test
-    public void testOrderWithAlias() {
-        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class)
-                .orderBy(Artist.PAINTING_ARRAY.alias("p1").dot(Painting.ESTIMATED_PRICE).asc())
-                .prefetch(Artist.PAINTING_ARRAY.disjoint());
-        List<Artist> artists = query.select(context);
-        assertEquals(5, artists.size());
-        assertEquals(2, artists.get(0).getPaintingArray().size());
-    }
-
-    @Test(expected = CayenneRuntimeException.class)
-    public void testPrefetchWithAliases() {
-        ObjectSelect<Artist> query = ObjectSelect.query(Artist.class);
-        query.prefetch(Artist.PAINTING_ARRAY.alias("p1").disjoint());
-        query.select(context);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
index 4d2ebab..5e8f95a 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
@@ -19,6 +19,15 @@
 
 package org.apache.cayenne.query;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.Fault;
 import org.apache.cayenne.ObjectContext;
@@ -46,21 +55,7 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 /**
  * @since 4.0

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
index ae06952..dd9e1f2 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelectTest.java
@@ -18,16 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -35,6 +25,16 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.junit.Test;
+
 public class ObjectSelectTest {
 
 	@Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
index b5910bc..80a67b4 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
@@ -19,9 +19,15 @@
 
 package org.apache.cayenne.query;
 
+import java.sql.Types;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.FunctionExpressionFactory;
 import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.property.NumericProperty;
 import org.apache.cayenne.exp.property.PropertyFactory;
@@ -36,13 +42,7 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import java.sql.Types;
-import java.text.DateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
+import static org.apache.cayenne.exp.FunctionExpressionFactory.*;
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -101,7 +101,7 @@ public class ObjectSelect_AggregateIT extends ServerCase {
                 .selectOne(context);
         assertEquals(20L, count);
     }
-    
+
     @Test
     public void testCountDistinct() throws Exception {
     	List<Artist> artists = ObjectSelect.query(Artist.class).select(context);
@@ -121,7 +121,7 @@ public class ObjectSelect_AggregateIT extends ServerCase {
     @Test
     @Ignore("Not all databases support AVG(DATE) aggregation")
     public void testAvg() throws Exception {
-        BaseProperty<Date> avgProp = PropertyFactory.createBase(FunctionExpressionFactory.avgExp(Artist.DATE_OF_BIRTH.getExpression()), Date.class);
+        BaseProperty<Date> avgProp = PropertyFactory.createBase(avgExp(Artist.DATE_OF_BIRTH.getExpression()), Date.class);
 
         Date avg = ObjectSelect.query(Artist.class)
                 .column(avgProp)
@@ -178,4 +178,4 @@ public class ObjectSelect_AggregateIT extends ServerCase {
         assertEquals("artist1", result[0]);
         assertEquals(4L, result[1]);
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
index df5632f..3414ba7 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
+import java.util.List;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ResultBatchIterator;
@@ -33,8 +35,6 @@ import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.List;
-
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fa1efbce/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
index 2352612..869a5e0 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
@@ -19,6 +19,17 @@
 
 package org.apache.cayenne.query;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.cayenne.Cayenne;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
@@ -46,17 +57,6 @@ import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.sql.Types;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
 @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
 public class SelectQueryIT extends ServerCase {