cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [5/6] cayenne git commit: CAY-2467 New type-aware Property API - cgen + templates - tests
Date Wed, 26 Dec 2018 12:19:09 GMT
http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
index 1d9e826..3fff74b 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
@@ -34,32 +34,32 @@ public class ExpressionEvaluateInMemoryTest {
 
 	@Test
 	public void testEvaluateADD() {
-		Expression add = new ASTAdd(new Object[] { new Integer(1), new Double(5.5) });
+		Expression add = new ASTAdd(1, 5.5);
 		assertEquals(6.5, ((Number) add.evaluate(null)).doubleValue(), 0.0001);
 	}
 
 	@Test
 	public void testEvaluateSubtract() {
-		Expression subtract = new ASTSubtract(new Object[] { new Integer(1), new Double(0.1), new Double(0.2) });
+		Expression subtract = new ASTSubtract(1, 0.1, 0.2);
 		assertEquals(0.7, ((Number) subtract.evaluate(null)).doubleValue(), 0.0001);
 	}
 
 	@Test
 	public void testEvaluateMultiply() {
-		Expression multiply = new ASTMultiply(new Object[] { new Integer(2), new Double(3.5) });
+		Expression multiply = new ASTMultiply(2, 3.5);
 		assertEquals(7, ((Number) multiply.evaluate(null)).doubleValue(), 0.0001);
 	}
 
 	@Test
 	public void testEvaluateDivide() {
-		Expression divide = new ASTDivide(new Object[] { new BigDecimal("7.0"), new BigDecimal("2.0") });
+		Expression divide = new ASTDivide(new BigDecimal("7.0"), new BigDecimal("2.0"));
 		assertEquals(3.5, ((Number) divide.evaluate(null)).doubleValue(), 0.0001);
 	}
 
 	@Test
 	public void testEvaluateNegate() {
-		assertEquals(-3, ((Number) new ASTNegate(new Integer(3)).evaluate(null)).intValue());
-		assertEquals(5, ((Number) new ASTNegate(new Integer(-5)).evaluate(null)).intValue());
+		assertEquals(-3, ((Number) new ASTNegate(Integer.valueOf(3)).evaluate(null)).intValue());
+		assertEquals(5, ((Number) new ASTNegate(Integer.valueOf(-5)).evaluate(null)).intValue());
 	}
 
 	@Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/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 5921085..04e45b5 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
@@ -33,14 +33,15 @@ import org.apache.cayenne.Fault;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.ResultBatchIterator;
-import org.apache.cayenne.ResultIteratorCallback;
 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.ExpressionFactory;
 import org.apache.cayenne.exp.FunctionExpressionFactory;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.testmap.Artist;
@@ -110,7 +111,7 @@ public class ColumnSelectIT extends ServerCase {
     @Test
     public void testSelectGroupBy() throws Exception {
         Object[] result = ObjectSelect.query(Artist.class)
-                .columns(Artist.DATE_OF_BIRTH, Property.COUNT)
+                .columns(Artist.DATE_OF_BIRTH, PropertyFactory.COUNT)
                 .orderBy(Artist.DATE_OF_BIRTH.asc())
                 .selectFirst(context);
 
@@ -121,7 +122,7 @@ public class ColumnSelectIT extends ServerCase {
     @Test
     public void testSelectSimpleHaving() throws Exception {
         Object[] result = ObjectSelect.query(Artist.class)
-                .columns(Artist.DATE_OF_BIRTH, Property.COUNT)
+                .columns(Artist.DATE_OF_BIRTH, PropertyFactory.COUNT)
                 .orderBy(Artist.DATE_OF_BIRTH.asc())
                 .having(Artist.DATE_OF_BIRTH.eq(dateFormat.parse("1/2/17")))
                 .selectOne(context);
@@ -131,10 +132,10 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test(expected = Exception.class)
-    public void testHavingOnNonGroupByColumn() throws Exception {
-        Property<String> nameSubstr = Artist.ARTIST_NAME.substring(1, 6);
+    public void testHavingOnNonGroupByColumn() {
+        StringProperty<String> nameSubstr = Artist.ARTIST_NAME.substring(1, 6);
 
-        Object[] q = ObjectSelect.columnQuery(Artist.class, nameSubstr, Property.COUNT)
+        Object[] q = ObjectSelect.columnQuery(Artist.class, nameSubstr, PropertyFactory.COUNT)
                 .having(Artist.ARTIST_NAME.like("artist%"))
                 .selectOne(context);
         assertEquals("artist", q[0]);
@@ -152,13 +153,13 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectHavingWithExpressionAlias() throws Exception {
+    public void testSelectHavingWithExpressionAlias() {
 
         Object[] q = null;
         try {
             q = ObjectSelect
-                    .columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6).alias("name_substr"), Property.COUNT)
-                    .having(Property.COUNT.gt(10L))
+                    .columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6).alias("name_substr"), PropertyFactory.COUNT)
+                    .having(PropertyFactory.COUNT.gt(10L))
                     .selectOne(context);
         } catch (CayenneRuntimeException ex) {
             if(unitDbAdapter.supportsExpressionInHaving()) {
@@ -173,12 +174,12 @@ public class ColumnSelectIT extends ServerCase {
 
     @Ignore("Need to figure out a better way to handle alias / no alias case for expression in having")
     @Test
-    public void testSelectHavingWithExpressionNoAlias() throws Exception {
+    public void testSelectHavingWithExpressionNoAlias() {
 
         Object[] q = null;
         try {
-            q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6), Property.COUNT)
-                    .having(Property.COUNT.gt(10L))
+            q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6), PropertyFactory.COUNT)
+                    .having(PropertyFactory.COUNT.gt(10L))
                     .selectOne(context);
         } catch (CayenneRuntimeException ex) {
             if(unitDbAdapter.supportsExpressionInHaving()) {
@@ -192,12 +193,12 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectWhereAndHaving() throws Exception {
+    public void testSelectWhereAndHaving() {
         Object[] q = null;
         try {
-            q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6).alias("name_substr"), Property.COUNT)
+            q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME.substring(1, 6).alias("name_substr"), PropertyFactory.COUNT)
                     .where(Artist.ARTIST_NAME.substring(1, 1).eq("a"))
-                    .having(Property.COUNT.gt(10L))
+                    .having(PropertyFactory.COUNT.gt(10L))
                     .selectOne(context);
         } catch (CayenneRuntimeException ex) {
             if(unitDbAdapter.supportsExpressionInHaving()) {
@@ -211,7 +212,7 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testHavingWithoutAggregate() throws Exception {
+    public void testHavingWithoutAggregate() {
         Object date = ObjectSelect.columnQuery(Artist.class, Artist.DATE_OF_BIRTH, Artist.ARTIST_NAME)
                 .having(Artist.ARTIST_NAME.like("a%"))
                 .selectFirst(context);
@@ -228,7 +229,7 @@ public class ColumnSelectIT extends ServerCase {
      */
     @Ignore
     @Test
-    public void testHavingWithoutSelect() throws Exception {
+    public void testHavingWithoutSelect() {
         Object date = ObjectSelect.columnQuery(Artist.class, Artist.DATE_OF_BIRTH)
                 .having(Artist.ARTIST_NAME.like("a%"))
                 .selectFirst(context);
@@ -241,7 +242,7 @@ public class ColumnSelectIT extends ServerCase {
      *      SELECT a.name FROM artist a JOIN painting p ON (..) HAVING COUNT(p.id) > 4
      */
     @Test
-    public void testSelectRelationshipCountHavingWithoutFieldSelect() throws Exception {
+    public void testSelectRelationshipCountHavingWithoutFieldSelect() {
         Object[] result = null;
         try {
             result = ObjectSelect.query(Artist.class)
@@ -260,8 +261,8 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectRelationshipCountHaving() throws Exception {
-        Property<Long> paintingCount = Artist.PAINTING_ARRAY.count();
+    public void testSelectRelationshipCountHaving() {
+        NumericProperty<Long> paintingCount = Artist.PAINTING_ARRAY.count();
 
         Object[] result = null;
         try {
@@ -281,13 +282,13 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectWithQuoting() throws Exception {
+    public void testSelectWithQuoting() {
         if(unitDbAdapter instanceof PostgresUnitDbAdapter) {
             // we need to convert somehow all names to lowercase on postgres, so skip it for now
             return;
         }
 
-        Property<Long> paintingCount = Artist.PAINTING_ARRAY.count();
+        NumericProperty<Long> paintingCount = Artist.PAINTING_ARRAY.count();
         context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(true);
 
         Object[] result = null;
@@ -319,7 +320,7 @@ public class ColumnSelectIT extends ServerCase {
         context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(true);
         try {
             Object[] result = ObjectSelect.query(Artist.class)
-                    .columns(Artist.DATE_OF_BIRTH, Property.COUNT)
+                    .columns(Artist.DATE_OF_BIRTH, PropertyFactory.COUNT)
                     .orderBy(Artist.DATE_OF_BIRTH.asc())
                     .selectFirst(context);
 
@@ -331,16 +332,17 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testAgregateOnRelation() throws Exception {
+    public void testAgregateOnRelation() {
         BigDecimal min = new BigDecimal(3);
         BigDecimal max = new BigDecimal(30);
         BigDecimal avg = new BigDecimal(BigInteger.valueOf(1290L), 2);
         BigDecimal sum = new BigDecimal(258);
 
-        Property<BigDecimal> estimatedPrice = Artist.PAINTING_ARRAY.dot(Painting.ESTIMATED_PRICE);
+        NumericProperty<BigDecimal> estimatedPrice = Artist.PAINTING_ARRAY.dot(Painting.ESTIMATED_PRICE);
         Object[] minMaxAvgPrice = ObjectSelect.query(Artist.class)
                 .where(estimatedPrice.gte(min))
-                .min(estimatedPrice).max(estimatedPrice)
+                .min(estimatedPrice)
+                .max(estimatedPrice)
                 .avg(estimatedPrice)
                 .sum(estimatedPrice)
                 .count()
@@ -354,9 +356,9 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testQueryCount() throws Exception {
+    public void testQueryCount() {
         long count = ObjectSelect
-                .columnQuery(Artist.class, Property.COUNT)
+                .columnQuery(Artist.class, PropertyFactory.COUNT)
                 .selectOne(context);
 
         assertEquals(20, count);
@@ -381,7 +383,7 @@ public class ColumnSelectIT extends ServerCase {
         tArtist.insert(22, "artist_21", null);
 
         long count = ObjectSelect
-                .columnQuery(Artist.class, Property.COUNT)
+                .columnQuery(Artist.class, PropertyFactory.COUNT)
                 .selectOne(context);
         assertEquals(22, count);
 
@@ -399,13 +401,13 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectFirst_MultiColumns() throws Exception {
+    public void testSelectFirst_MultiColumns() {
         Object[] a = ObjectSelect.query(Artist.class)
                 .columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH)
                 .columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH)
                 .columns(Artist.ARTIST_NAME.alias("newName"))
                 .where(Artist.ARTIST_NAME.like("artist%"))
-                .orderBy("db:ARTIST_ID")
+                .orderBy(Artist.ARTIST_ID_PK_PROPERTY.asc())
                 .selectFirst(context);
         assertNotNull(a);
         assertEquals("artist1", a[0]);
@@ -413,20 +415,19 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectFirst_SingleValueInColumns() throws Exception {
+    public void testSelectFirst_SingleValueInColumns() {
         Object[] a = ObjectSelect.query(Artist.class)
                 .columns(Artist.ARTIST_NAME)
                 .where(Artist.ARTIST_NAME.like("artist%"))
-                .orderBy("db:ARTIST_ID")
+                .orderBy(Artist.ARTIST_ID_PK_PROPERTY.asc())
                 .selectFirst(context);
         assertNotNull(a);
         assertEquals("artist1", a[0]);
     }
 
     @Test
-    public void testSelectFirst_SubstringName() throws Exception {
-        Expression exp = FunctionExpressionFactory.substringExp(Artist.ARTIST_NAME.path(), 5, 3);
-        Property<String> substrName = Property.create("substrName", exp, String.class);
+    public void testSelectFirst_SubstringName() {
+        StringProperty<String> substrName = Artist.ARTIST_NAME.substring(5, 3);
         Object[] a = ObjectSelect.query(Artist.class)
                 .columns(Artist.ARTIST_NAME, substrName)
                 .where(substrName.eq("st3"))
@@ -438,9 +439,9 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectFirst_RelColumns() throws Exception {
+    public void testSelectFirst_RelColumns() {
         // set shorter than painting_array.paintingTitle alias as some DBs doesn't support dot in alias
-        Property<String> paintingTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).alias("paintingTitle");
+        StringProperty<String> paintingTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).alias("paintingTitle");
 
         Object[] a = ObjectSelect.query(Artist.class)
                 .columns(Artist.ARTIST_NAME, paintingTitle)
@@ -451,9 +452,9 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectFirst_RelColumn() throws Exception {
+    public void testSelectFirst_RelColumn() {
         // set shorter than painting_array.paintingTitle alias as some DBs doesn't support dot in alias
-        Property<String> paintingTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).alias("paintingTitle");
+        StringProperty<String> paintingTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).alias("paintingTitle");
 
         String a = ObjectSelect.query(Artist.class)
                 .column(paintingTitle)
@@ -464,8 +465,8 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testSelectFirst_RelColumnWithFunction() throws Exception {
-        Property<String> altTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE)
+    public void testSelectFirst_RelColumnWithFunction() {
+        StringProperty<String> altTitle = Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE)
                 .substring(7, 3).concat(" ", Artist.ARTIST_NAME)
                 .alias("altTitle");
 
@@ -484,12 +485,12 @@ public class ColumnSelectIT extends ServerCase {
         // test that all table aliases are correct
         List<Object[]> result = ObjectSelect.columnQuery(Artist.class,
                 Artist.PAINTING_ARRAY.outer().count(),
-                Property.createSelf(Artist.class),
+                PropertyFactory.createSelf(Artist.class),
                 Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE),
-                Property.createSelf(Artist.class),
+                PropertyFactory.createSelf(Artist.class),
                 Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY).dot(Gallery.GALLERY_NAME),
                 Artist.ARTIST_NAME,
-                Property.createSelf(Artist.class)
+                PropertyFactory.createSelf(Artist.class)
         ).select(context);
         assertEquals(21, result.size());
         for(Object[] next : result) {
@@ -507,6 +508,7 @@ public class ColumnSelectIT extends ServerCase {
             assertEquals(PersistenceState.COMMITTED, artist.getPersistenceState());
             assertEquals(PersistenceState.COMMITTED, artist2.getPersistenceState());
             assertEquals(PersistenceState.COMMITTED, artist3.getPersistenceState());
+            assertEquals(artistName, artist.getArtistName());
         }
     }
 
@@ -515,23 +517,20 @@ public class ColumnSelectIT extends ServerCase {
      */
 
     @Test
-    public void testIterationSingleColumn() throws Exception {
+    public void testIterationSingleColumn() {
         ColumnSelect<String> columnSelect = ObjectSelect.query(Artist.class).column(Artist.ARTIST_NAME);
 
         final int[] count = new int[1];
-        columnSelect.iterate(context, new ResultIteratorCallback<String>() {
-            @Override
-            public void next(String object) {
-                count[0]++;
-                assertTrue(object.startsWith("artist"));
-            }
+        columnSelect.iterate(context, object -> {
+            count[0]++;
+            assertTrue(object.startsWith("artist"));
         });
 
         assertEquals(20, count[0]);
     }
 
     @Test
-    public void testBatchIterationSingleColumn() throws Exception {
+    public void testBatchIterationSingleColumn() {
         ColumnSelect<String> columnSelect = ObjectSelect.query(Artist.class).column(Artist.ARTIST_NAME);
 
         try(ResultBatchIterator<String> it = columnSelect.batchIterator(context, 10)) {
@@ -542,24 +541,21 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testIterationMultiColumns() throws Exception {
+    public void testIterationMultiColumns() {
         ColumnSelect<Object[]> columnSelect = ObjectSelect.query(Artist.class).columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH);
 
         final int[] count = new int[1];
-        columnSelect.iterate(context, new ResultIteratorCallback<Object[]>() {
-            @Override
-            public void next(Object[] object) {
-                count[0]++;
-                assertTrue(object[0] instanceof String);
-                assertTrue(object[1] instanceof java.util.Date);
-            }
+        columnSelect.iterate(context, object -> {
+            count[0]++;
+            assertTrue(object[0] instanceof String);
+            assertTrue(object[1] instanceof Date);
         });
 
         assertEquals(20, count[0]);
     }
 
     @Test
-    public void testBatchIterationMultiColumns() throws Exception {
+    public void testBatchIterationMultiColumns() {
         ColumnSelect<Object[]> columnSelect = ObjectSelect.query(Artist.class).columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH);
 
         try(ResultBatchIterator<Object[]> it = columnSelect.batchIterator(context, 10)) {
@@ -625,7 +621,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testPageSizeOneObject() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
         List<Artist> a = ObjectSelect.query(Artist.class)
                 .column(artistFull)
                 .pageSize(10)
@@ -639,7 +635,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testPageSizeOneObjectAsArray() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
         List<Object[]> a = ObjectSelect.query(Artist.class)
                 .columns(artistFull)
                 .pageSize(10)
@@ -654,7 +650,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testPageSizeObjectAndScalars() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
         List<Object[]> a = ObjectSelect.query(Artist.class)
                 .columns(Artist.ARTIST_NAME, artistFull, Artist.PAINTING_ARRAY.count())
                 .pageSize(10)
@@ -673,9 +669,9 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testPageSizeObjects() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
         List<Object[]> a = ObjectSelect.query(Artist.class)
-                .columns(Artist.ARTIST_NAME, artistFull, Artist.PAINTING_ARRAY.flat(Painting.class))
+                .columns(Artist.ARTIST_NAME, artistFull, Artist.PAINTING_ARRAY.flat())
                 .pageSize(10)
                 .select(context);
         assertNotNull(a);
@@ -696,7 +692,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testObjectColumnWithJointPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE))
@@ -708,7 +704,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testObjectColumnWithDisjointPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE))
@@ -720,7 +716,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testObjectColumnWithDisjointByIdPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE))
@@ -747,7 +743,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testAggregateColumnWithJointPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.PAINTING_ARRAY.count())
@@ -759,7 +755,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testAggregateColumnWithDisjointPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.PAINTING_ARRAY.count())
@@ -771,7 +767,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testAggregateColumnWithDisjointByIdPrefetch() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
                 .columns(artistFull, Artist.PAINTING_ARRAY.count())
@@ -791,14 +787,14 @@ public class ColumnSelectIT extends ServerCase {
 
             Object paintingsArr = artist.readPropertyDirectly(Artist.PAINTING_ARRAY.getName());
             assertFalse(paintingsArr instanceof Fault);
-            assertTrue(((List)paintingsArr).size() == (long)next[1]);
+            assertEquals(((List) paintingsArr).size(), (long) next[1]);
         }
     }
 
     @Test
     public void testObjectSelectWithJointPrefetch() {
         List<Artist> result = ObjectSelect.query(Artist.class)
-                .column(Property.createSelf(Artist.class))
+                .column(PropertyFactory.createSelf(Artist.class))
                 .prefetch(Artist.PAINTING_ARRAY.joint())
                 .select(context);
         assertEquals(20, result.size());
@@ -814,7 +810,7 @@ public class ColumnSelectIT extends ServerCase {
     @Test
     public void testObjectWithDisjointPrefetch() {
         List<Artist> result = ObjectSelect.query(Artist.class)
-                .column(Property.createSelf(Artist.class))
+                .column(PropertyFactory.createSelf(Artist.class))
                 .prefetch(Artist.PAINTING_ARRAY.disjoint())
                 .select(context);
         assertEquals(20, result.size());
@@ -829,7 +825,7 @@ public class ColumnSelectIT extends ServerCase {
     @Test
     public void testObjectWithDisjointByIdPrefetch() {
         List<Artist> result = ObjectSelect.query(Artist.class)
-                .column(Property.createSelf(Artist.class))
+                .column(PropertyFactory.createSelf(Artist.class))
                 .prefetch(Artist.PAINTING_ARRAY.disjointById())
                 .select(context);
         assertEquals(20, result.size());
@@ -847,10 +843,10 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testObjectColumn() {
-        Property<Artist> artistFull = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
-                .columns(artistFull, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
+                .columns(artistProperty, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
                 .select(context);
         assertEquals(5, result.size());
 
@@ -864,8 +860,8 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test
     public void testObjectColumnToOne() {
-        Property<Artist> artistFull = Property.create(ExpressionFactory.fullObjectExp(Painting.TO_ARTIST.getExpression()), Artist.class);
-        Property<Gallery> galleryFull = Property.create(ExpressionFactory.fullObjectExp(Painting.TO_GALLERY.getExpression()), Gallery.class);
+        EntityProperty<Artist> artistFull = PropertyFactory.createSelf(Painting.TO_ARTIST.getExpression(), Artist.class);
+        EntityProperty<Gallery> galleryFull = PropertyFactory.createSelf(Painting.TO_GALLERY.getExpression(), Gallery.class);
 
         List<Object[]> result = ObjectSelect.query(Painting.class)
                 .columns(Painting.PAINTING_TITLE, artistFull, galleryFull)
@@ -897,11 +893,11 @@ public class ColumnSelectIT extends ServerCase {
     }
 
     @Test
-    public void testObjectColumnToMany() throws Exception {
-        Property<Artist> artist = Property.createSelf(Artist.class);
+    public void testObjectColumnToMany() {
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
 
         List<Object[]> result = ObjectSelect.query(Artist.class)
-                .columns(artist, Artist.PAINTING_ARRAY.flat(Painting.class), Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY))
+                .columns(artistProperty, Artist.PAINTING_ARRAY.flat(), Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY))
                 .select(context);
         assertEquals(21, result.size());
 
@@ -925,7 +921,7 @@ public class ColumnSelectIT extends ServerCase {
 
     @Test(expected = CayenneRuntimeException.class)
     public void testSelfPropertyInOrderBy() {
-        Property<Artist> artistProperty = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
         ObjectSelect.query(Artist.class)
                 .column(artistProperty)
                 .orderBy(artistProperty.desc())
@@ -935,18 +931,19 @@ public class ColumnSelectIT extends ServerCase {
     @Test(expected = CayenneRuntimeException.class)
     public void testSelfPropertyInWhere() {
         Artist artist = ObjectSelect.query(Artist.class).selectFirst(context);
-        Property<Artist> artistProperty = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
         List<Artist> result = ObjectSelect.query(Artist.class)
                 .column(artistProperty)
                 .where(artistProperty.eq(artist))
                 .select(context);
+        assertNotNull(result);
     }
 
     @Test
     public void testObjPropertyInWhere() {
         Artist artist = ObjectSelect.query(Artist.class, Artist.ARTIST_NAME.eq("artist1"))
                 .selectFirst(context);
-        Property<Painting> paintingProperty = Property.createSelf(Painting.class);
+        EntityProperty<Painting> paintingProperty = PropertyFactory.createSelf(Painting.class);
         List<Painting> result = ObjectSelect.query(Painting.class)
                 .column(paintingProperty)
                 .where(Painting.TO_ARTIST.eq(artist))
@@ -1027,7 +1024,7 @@ public class ColumnSelectIT extends ServerCase {
     public void testNestedContextObjectResult() {
         ObjectContext childContext = runtime.newContext(context);
 
-        Property<Artist> artistProperty = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
         List<Artist> artists = ObjectSelect.columnQuery(Artist.class, artistProperty)
                 .select(childContext);
         assertEquals(20, artists.size());
@@ -1053,7 +1050,7 @@ public class ColumnSelectIT extends ServerCase {
     public void testNestedContextMixedResult() {
         ObjectContext childContext = runtime.newContext(context);
 
-        Property<Artist> artistProperty = Property.createSelf(Artist.class);
+        EntityProperty<Artist> artistProperty = PropertyFactory.createSelf(Artist.class);
         List<Object[]> data = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, artistProperty)
                 .select(childContext);
         assertEquals(20, data.size());
@@ -1080,4 +1077,16 @@ public class ColumnSelectIT extends ServerCase {
         assertArrayEquals(new byte[]{(byte)5, (byte)4, (byte)3, (byte)2}, blobs.get(1));
     }
 
+    @Test
+    public void testCollectionProperty() {
+        Painting painting = ObjectSelect.query(Painting.class).selectFirst(context);
+
+        Artist artist = ObjectSelect.query(Artist.class)
+                .where(Artist.PAINTING_ARRAY.contains(painting))
+                .and(Artist.DATE_OF_BIRTH.year().gt(1950))
+                .and(Artist.ARTIST_NAME.like("artist%"))
+                .selectOne(context);
+        assertNotNull(artist);
+        assertTrue(artist.getArtistName().startsWith("artist"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
index eb09967..96c4017 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
@@ -24,9 +24,10 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
+import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.apache.cayenne.testdo.testmap.Painting;
 import org.junit.Test;
@@ -39,7 +40,7 @@ import static org.junit.Assert.*;
 public class ColumnSelectTest {
 
     @Test
-    public void query() throws Exception {
+    public void query() {
         ColumnSelect<Artist> q = new ColumnSelect<>();
         assertNull(q.getColumns());
         assertNull(q.getHaving());
@@ -47,7 +48,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryWithOneColumn() throws Exception {
+    public void queryWithOneColumn() {
         ColumnSelect<String> q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME);
         assertEquals(Collections.singletonList(Artist.ARTIST_NAME), q.getColumns());
         assertTrue(q.singleColumn);
@@ -56,7 +57,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryWithOneColumn2() throws Exception {
+    public void queryWithOneColumn2() {
         ColumnSelect<String> q = ObjectSelect.query(Artist.class).column(Artist.ARTIST_NAME);
         assertEquals(Collections.singletonList(Artist.ARTIST_NAME), q.getColumns());
         assertTrue(q.singleColumn);
@@ -65,7 +66,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryWithOneColumn3() throws Exception {
+    public void queryWithOneColumn3() {
         ColumnSelect<Object[]> q = ObjectSelect.query(Artist.class).columns(Artist.ARTIST_NAME);
         assertEquals(Collections.singletonList(Artist.ARTIST_NAME), q.getColumns());
         assertFalse(q.singleColumn);
@@ -74,7 +75,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryWithMultipleColumns() throws Exception {
+    public void queryWithMultipleColumns() {
         ColumnSelect<Object[]> q = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH);
         assertEquals(Arrays.asList(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH), q.getColumns());
         assertFalse(q.singleColumn);
@@ -83,15 +84,15 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryCount() throws Exception {
+    public void queryCount() {
         ColumnSelect<Long> q = ObjectSelect.query(Artist.class).count();
-        assertEquals(Collections.singletonList(Property.COUNT), q.getColumns());
+        assertEquals(Collections.singletonList(PropertyFactory.COUNT), q.getColumns());
         assertNull(q.getHaving());
         assertNull(q.getWhere());
     }
 
     @Test
-    public void queryCountWithProperty() throws Exception {
+    public void queryCountWithProperty() {
         ColumnSelect<Long> q = ObjectSelect.query(Artist.class).count(Artist.ARTIST_NAME);
         assertEquals(Collections.singletonList(Artist.ARTIST_NAME.count()), q.getColumns());
         assertNull(q.getHaving());
@@ -99,7 +100,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void queryMinWithProperty() throws Exception {
+    public void queryMinWithProperty() {
         ColumnSelect<BigDecimal> q = ObjectSelect.query(Artist.class).min(Artist.PAINTING_ARRAY.dot(Painting.ESTIMATED_PRICE));
         assertEquals(Collections.singletonList(Artist.PAINTING_ARRAY.dot(Painting.ESTIMATED_PRICE).min()), q.getColumns());
         assertNull(q.getHaving());
@@ -108,7 +109,7 @@ public class ColumnSelectTest {
 
     @SuppressWarnings("unchecked")
     @Test
-    public void columns() throws Exception {
+    public void columns() {
         ColumnSelect q = new ColumnSelect();
         assertNull(q.getColumns());
         q.columns(Artist.ARTIST_NAME, Artist.PAINTING_ARRAY);
@@ -122,7 +123,7 @@ public class ColumnSelectTest {
 
 
     @Test
-    public void havingExpression() throws Exception {
+    public void havingExpression() {
         ColumnSelect q = new ColumnSelect();
         assertNull(q.getHaving());
         assertNull(q.getWhere());
@@ -139,7 +140,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void havingString() throws Exception {
+    public void havingString() {
         ColumnSelect q = new ColumnSelect();
         assertNull(q.getHaving());
         assertNull(q.getWhere());
@@ -156,7 +157,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void and() throws Exception {
+    public void and() {
         ColumnSelect q = new ColumnSelect();
         assertNull(q.getHaving());
         assertNull(q.getWhere());
@@ -175,7 +176,7 @@ public class ColumnSelectTest {
     }
 
     @Test
-    public void or() throws Exception {
+    public void or() {
         ColumnSelect q = new ColumnSelect();
         assertNull(q.getHaving());
         assertNull(q.getWhere());
@@ -198,13 +199,13 @@ public class ColumnSelectTest {
     public void testColumnsAddByOne() {
         ColumnSelect<Artist> q = new ColumnSelect<>();
 
-        assertEquals(null, q.getColumns());
+        assertNull(q.getColumns());
 
         q.columns(Artist.ARTIST_NAME);
         q.columns(Artist.DATE_OF_BIRTH);
         q.columns(Artist.PAINTING_ARRAY);
 
-        Collection<Property<?>> properties = Arrays.asList(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY);
+        Collection<BaseProperty<?>> properties = Arrays.asList(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY);
         assertEquals(properties, q.getColumns());
     }
 
@@ -212,12 +213,12 @@ public class ColumnSelectTest {
     public void testColumnsAddAll() {
         ColumnSelect<Artist> q = new ColumnSelect<>();
 
-        assertEquals(null, q.getColumns());
+        assertNull(q.getColumns());
 
         q.columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY);
         q.columns(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY);
 
-        Collection<Property<?>> properties = Arrays.asList(
+        Collection<BaseProperty<?>> properties = Arrays.asList(
                 Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY,
                 Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH, Artist.PAINTING_ARRAY); // should it be Set instead of List?
         assertEquals(properties, q.getColumns());
@@ -227,13 +228,13 @@ public class ColumnSelectTest {
     public void testColumnAddByOne() {
         ColumnSelect<Artist> q = new ColumnSelect<>();
 
-        assertEquals(null, q.getColumns());
+        assertNull(q.getColumns());
 
         q.column(Artist.ARTIST_NAME);
         q.column(Artist.DATE_OF_BIRTH);
         q.column(Artist.PAINTING_ARRAY);
 
-        Collection<Property<?>> properties = Collections.<Property<?>>singletonList(Artist.PAINTING_ARRAY);
+        Collection<BaseProperty<?>> properties = Collections.singletonList(Artist.PAINTING_ARRAY);
         assertEquals(properties, q.getColumns());
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/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 d789e41..e88c7cd 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
@@ -28,7 +28,9 @@ import java.util.Locale;
 
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.testmap.Artist;
@@ -93,11 +95,9 @@ public class ObjectSelect_AggregateIT extends ServerCase {
     }
 
     @Test
-    public void testCount() throws Exception {
-        Property<Long> countProp = Property.create(countExp(), Long.class);
-
+    public void testCount() {
         long count = ObjectSelect.query(Artist.class)
-                .column(countProp)
+                .column(PropertyFactory.COUNT)
                 .selectOne(context);
         assertEquals(20L, count);
     }
@@ -110,7 +110,7 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 		}
     	context.commitChanges();
     	
-        Property<Long> countDistinctProp = Artist.ARTIST_NAME.countDistinct();
+        NumericProperty<Long> countDistinctProp = Artist.ARTIST_NAME.countDistinct();
 
         long count = ObjectSelect.query(Artist.class)
                 .column(countDistinctProp)
@@ -121,7 +121,7 @@ public class ObjectSelect_AggregateIT extends ServerCase {
     @Test
     @Ignore("Not all databases support AVG(DATE) aggregation")
     public void testAvg() throws Exception {
-        Property<Date> avgProp = Property.create(avgExp(Artist.DATE_OF_BIRTH.path()), Date.class);
+        BaseProperty<Date> avgProp = PropertyFactory.createBase(avgExp(Artist.DATE_OF_BIRTH.getExpression()), Date.class);
 
         Date avg = ObjectSelect.query(Artist.class)
                 .column(avgProp)
@@ -132,10 +132,8 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testMin() throws Exception {
-        Property<Date> minProp = Property.create(minExp(Artist.DATE_OF_BIRTH.path()), Date.class);
-
         Date avg = ObjectSelect.query(Artist.class)
-                .column(minProp)
+                .column(Artist.DATE_OF_BIRTH.min())
                 .selectOne(context);
         Date date = dateFormat.parse("1/1/17");
         assertEquals(date, avg);
@@ -143,10 +141,8 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testMax() throws Exception {
-        Property<Date> maxProp = Property.create(maxExp(Artist.DATE_OF_BIRTH.path()), Date.class);
-
         Date avg = ObjectSelect.query(Artist.class)
-                .column(maxProp)
+                .column(Artist.DATE_OF_BIRTH.max())
                 .selectOne(context);
         Date date = dateFormat.parse("1/5/17");
         assertEquals(date, avg);
@@ -154,10 +150,8 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testCountGroupBy() throws Exception {
-        Property<Long> countProp = Property.create(countExp(Artist.ARTIST_NAME.path()), Long.class);
-
         List<Object[]> count = ObjectSelect.query(Artist.class)
-                .columns(countProp, Artist.DATE_OF_BIRTH)
+                .columns(Artist.ARTIST_NAME.count(), Artist.DATE_OF_BIRTH)
                 .orderBy(Artist.DATE_OF_BIRTH.asc())
                 .select(context);
         Date date = dateFormat.parse("1/2/17");
@@ -168,10 +162,8 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testSelectRelationshipCount() throws Exception {
-        Property<Long> paintingCount = Property.create(countExp(Artist.PAINTING_ARRAY.path()), Long.class);
-
         long count = ObjectSelect.query(Artist.class)
-                .column(paintingCount)
+                .column(Artist.PAINTING_ARRAY.count())
                 .where(Artist.ARTIST_NAME.eq("artist1"))
                 .selectOne(context);
         assertEquals(4L, count);
@@ -179,10 +171,8 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testSelectRelationshipCountWithAnotherField() throws Exception {
-        Property<Long> paintingCount = Property.create(countExp(Artist.PAINTING_ARRAY.path()), Long.class);
-
         Object[] result = ObjectSelect.query(Artist.class)
-                .columns(Artist.ARTIST_NAME, paintingCount)
+                .columns(Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
                 .where(Artist.ARTIST_NAME.eq("artist1"))
                 .selectOne(context);
         assertEquals("artist1", result[0]);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_CompileIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_CompileIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_CompileIT.java
index f395227..caecb15 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_CompileIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_CompileIT.java
@@ -25,7 +25,7 @@ import org.apache.cayenne.CayenneDataObject;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
@@ -181,7 +181,7 @@ public class ObjectSelect_CompileIT extends ServerCase {
 		SelectQuery selectQuery2 = (SelectQuery) newQ.createReplacementQuery(resolver);
 		assertNotNull(selectQuery2.getColumns());
 
-		Collection<Property<?>> properties = Arrays.<Property<?>>asList(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH);
+		Collection<BaseProperty<?>> properties = Arrays.asList(Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH);
 		assertEquals(properties, selectQuery2.getColumns());
 	}
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
index 15326e6..9c97101 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
@@ -24,7 +24,9 @@ import java.util.List;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.primitive.PrimitivesTestEntity;
@@ -35,10 +37,9 @@ import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.apache.cayenne.exp.FunctionExpressionFactory.avgExp;
-import static org.apache.cayenne.exp.FunctionExpressionFactory.sumExp;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 /**
  * @since 4.0
@@ -66,7 +67,7 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void test_SelectIntegerColumn() throws Exception {
+    public void test_SelectIntegerColumn() {
         int intColumn2 = ObjectSelect.query(PrimitivesTestEntity.class)
                 .column(PrimitivesTestEntity.INT_COLUMN)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
@@ -75,7 +76,7 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void test_SelectIntegerList() throws Exception {
+    public void test_SelectIntegerList() {
         List<Integer> intColumns = ObjectSelect.query(PrimitivesTestEntity.class)
                 .column(PrimitivesTestEntity.INT_COLUMN)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
@@ -85,8 +86,8 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void test_SelectIntegerExpColumn() throws Exception {
-        Property<Integer> property = Property.create("intColumn",
+    public void test_SelectIntegerExpColumn() {
+        NumericProperty<Integer> property = PropertyFactory.createNumeric("intColumn",
                 ExpressionFactory.exp("(obj:intColumn + obj:intColumn)"), Integer.class);
 
         int intColumn2 = ObjectSelect.query(PrimitivesTestEntity.class)
@@ -97,42 +98,42 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void test_SelectBooleanColumn() throws Exception {
+    public void test_SelectBooleanColumn() {
         boolean boolColumn = ObjectSelect.query(PrimitivesTestEntity.class)
                 .column(PrimitivesTestEntity.BOOLEAN_COLUMN)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
                 .selectFirst(context);
-        assertEquals(false, boolColumn);
+        assertFalse(boolColumn);
     }
 
     @Test
-    public void test_SelectBooleanList() throws Exception {
+    public void test_SelectBooleanList() {
         List<Boolean> intColumns = ObjectSelect.query(PrimitivesTestEntity.class)
                 .column(PrimitivesTestEntity.BOOLEAN_COLUMN)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
                 .select(context);
         assertEquals(20, intColumns.size());
-        assertEquals(false, intColumns.get(0));
+        assertFalse(intColumns.get(0));
     }
 
     @Test
-    public void test_SelectBooleanExpColumn() throws Exception {
+    public void test_SelectBooleanExpColumn() {
         if(!unitDbAdapter.supportsSelectBooleanExpression()) {
             return;
         }
 
-        Property<Boolean> property = Property.create("boolColumn",
+        BaseProperty<Boolean> property = PropertyFactory.createBase("boolColumn",
                 ExpressionFactory.exp("(obj:intColumn < 10)"), Boolean.class);
 
         boolean boolColumn = ObjectSelect.query(PrimitivesTestEntity.class)
                 .column(property)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
                 .selectFirst(context);
-        assertEquals(false, boolColumn);
+        assertFalse(boolColumn);
     }
 
     @Test
-    public void test_SelectColumnsList() throws Exception {
+    public void test_SelectColumnsList() {
         List<Object[]> columns = ObjectSelect.query(PrimitivesTestEntity.class)
                 .columns(PrimitivesTestEntity.INT_COLUMN, PrimitivesTestEntity.BOOLEAN_COLUMN)
                 .orderBy(PrimitivesTestEntity.INT_COLUMN.asc())
@@ -144,15 +145,15 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void test_SelectColumnsExpList() throws Exception {
+    public void test_SelectColumnsExpList() {
         if(!unitDbAdapter.supportsSelectBooleanExpression()) {
             return;
         }
 
-        Property<Integer> intProperty = Property.create("intColumn",
+        NumericProperty<Integer> intProperty = PropertyFactory.createNumeric("intColumn",
                 ExpressionFactory.exp("(obj:intColumn + 1)"), Integer.class);
 
-        Property<Boolean> boolProperty = Property.create("boolColumn",
+        BaseProperty<Boolean> boolProperty = PropertyFactory.createBase("boolColumn",
                 ExpressionFactory.exp("(obj:intColumn = 10)"), Boolean.class);
 
         List<Object[]> columns = ObjectSelect.query(PrimitivesTestEntity.class)
@@ -166,7 +167,7 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void testSum() throws Exception {
+    public void testSum() {
         int sum = ObjectSelect.query(PrimitivesTestEntity.class)
                 .sum(PrimitivesTestEntity.INT_COLUMN)
                 .selectOne(context);
@@ -174,7 +175,7 @@ public class ObjectSelect_PrimitiveColumnsIT extends ServerCase {
     }
 
     @Test
-    public void testAvg() throws Exception {
+    public void testAvg() {
         int avg = ObjectSelect.query(PrimitivesTestEntity.class)
                 .avg(PrimitivesTestEntity.INT_COLUMN)
                 .selectOne(context);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/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 2f6eba9..c353e1c 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
@@ -26,9 +26,6 @@ import org.apache.cayenne.ResultBatchIterator;
 import org.apache.cayenne.ResultIterator;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.FunctionExpressionFactory;
-import org.apache.cayenne.exp.Property;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.testmap.Artist;
@@ -101,17 +98,17 @@ public class ObjectSelect_RunIT extends ServerCase {
 		try (ResultIterator<Artist> it = ObjectSelect.query(Artist.class).iterator(context)) {
 			int count = 0;
 
-			for (Artist a : it) {
+			while(it.hasNextRow()) {
+				it.nextRow();
 				count++;
 			}
-
 			assertEquals(20, count);
 		}
 	}
 
 	@Test
 	public void test_BatchIterator() {
-		try (ResultBatchIterator<Artist> it = ObjectSelect.query(Artist.class).batchIterator(context, 5);) {
+		try (ResultBatchIterator<Artist> it = ObjectSelect.query(Artist.class).batchIterator(context, 5)) {
 			int count = 0;
 
 			for (List<Artist> artistList : it) {
@@ -176,27 +173,25 @@ public class ObjectSelect_RunIT extends ServerCase {
 	@Test
 	public void test_SelectFirst_MoreThanOneMatch() {
 		Artist a = ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.like("artist%"))
-				.orderBy("db:ARTIST_ID").selectFirst(context);
+				.orderBy(Artist.ARTIST_ID_PK_PROPERTY.asc()).selectFirst(context);
 		assertNotNull(a);
 		assertEquals("artist1", a.getArtistName());
 	}
 
 	@Test
 	public void test_SelectFirst_TrimInWhere() {
-		Expression exp = FunctionExpressionFactory.trimExp(Artist.ARTIST_NAME.path());
-		Property<String> trimmedName = Property.create("trimmed", exp, String.class);
-		Artist a = ObjectSelect.query(Artist.class).where(trimmedName.likeIgnoreCase("artist%"))
-				.orderBy("db:ARTIST_ID").selectFirst(context);
+		Artist a = ObjectSelect.query(Artist.class)
+				.where(Artist.ARTIST_NAME.trim().likeIgnoreCase("artist%"))
+				.orderBy(Artist.ARTIST_ID_PK_PROPERTY.asc()).selectFirst(context);
 		assertNotNull(a);
 		assertEquals("artist1", a.getArtistName());
 	}
 
 	@Test
 	public void test_SelectFirst_SubstringInWhere() {
-		Expression exp = FunctionExpressionFactory.substringExp(Artist.ARTIST_NAME.path(), 2, 3);
-		Property<String> substrName = Property.create("substr", exp, String.class);
-		Artist a = ObjectSelect.query(Artist.class).where(substrName.eq("rti"))
-				.orderBy("db:ARTIST_ID").selectFirst(context);
+		Artist a = ObjectSelect.query(Artist.class)
+				.where(Artist.ARTIST_NAME.substring(2, 3).eq("rti"))
+				.orderBy(Artist.ARTIST_ID_PK_PROPERTY.asc()).selectFirst(context);
 		assertNotNull(a);
 		assertEquals("artist1", a.getArtistName());
 	}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharFkTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharFkTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharFkTestEntity.java
index 4d93574..195b054 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharFkTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharFkTestEntity.java
@@ -5,7 +5,9 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.compound.CharPkTestEntity;
 
 /**
@@ -20,8 +22,8 @@ public abstract class _CharFkTestEntity extends BaseDataObject {
 
     public static final String PK_PK_COLUMN = "PK";
 
-    public static final Property<String> NAME = Property.create("name", String.class);
-    public static final Property<CharPkTestEntity> TO_CHAR_PK = Property.create("toCharPK", CharPkTestEntity.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+    public static final EntityProperty<CharPkTestEntity> TO_CHAR_PK = PropertyFactory.createEntity("toCharPK", CharPkTestEntity.class);
 
     protected String name;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharPkTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharPkTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharPkTestEntity.java
index d14d598..70253d9 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharPkTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CharPkTestEntity.java
@@ -6,7 +6,9 @@ import java.io.ObjectOutputStream;
 import java.util.List;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.ListProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.compound.CharFkTestEntity;
 
 /**
@@ -21,9 +23,9 @@ public abstract class _CharPkTestEntity extends BaseDataObject {
 
     public static final String PK_COL_PK_COLUMN = "PK_COL";
 
-    public static final Property<String> OTHER_COL = Property.create("otherCol", String.class);
-    public static final Property<String> PK_COL = Property.create("pkCol", String.class);
-    public static final Property<List<CharFkTestEntity>> CHAR_FKS = Property.create("charFKs", List.class);
+    public static final StringProperty<String> OTHER_COL = PropertyFactory.createString("otherCol", String.class);
+    public static final StringProperty<String> PK_COL = PropertyFactory.createString("pkCol", String.class);
+    public static final ListProperty<CharFkTestEntity> CHAR_FKS = PropertyFactory.createList("charFKs", CharFkTestEntity.class);
 
     protected String otherCol;
     protected String pkCol;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundFkTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundFkTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundFkTestEntity.java
index cf2f6f3..3ec04a0 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundFkTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundFkTestEntity.java
@@ -5,7 +5,9 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.compound.CompoundPkTestEntity;
 
 /**
@@ -20,8 +22,8 @@ public abstract class _CompoundFkTestEntity extends BaseDataObject {
 
     public static final String PKEY_PK_COLUMN = "PKEY";
 
-    public static final Property<String> NAME = Property.create("name", String.class);
-    public static final Property<CompoundPkTestEntity> TO_COMPOUND_PK = Property.create("toCompoundPk", CompoundPkTestEntity.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+    public static final EntityProperty<CompoundPkTestEntity> TO_COMPOUND_PK = PropertyFactory.createEntity("toCompoundPk", CompoundPkTestEntity.class);
 
     protected String name;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundIntPk.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundIntPk.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundIntPk.java
index 58ab110..b0bf34e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundIntPk.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundIntPk.java
@@ -1,7 +1,13 @@
 package org.apache.cayenne.testdo.compound.auto;
 
-import org.apache.cayenne.CayenneDataObject;
-import org.apache.cayenne.exp.Property;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 
 /**
  * Class _CompoundIntPk was generated by Cayenne.
@@ -9,36 +15,113 @@ import org.apache.cayenne.exp.Property;
  * since it may be overwritten next time code is regenerated.
  * If you need to make any customizations, please use subclass.
  */
-public abstract class _CompoundIntPk extends CayenneDataObject {
+public abstract class _CompoundIntPk extends BaseDataObject {
 
     private static final long serialVersionUID = 1L; 
 
     public static final String ID1_PK_COLUMN = "id1";
     public static final String ID2_PK_COLUMN = "id2";
 
-    public static final Property<Integer> ID1 = Property.create("id1", Integer.class);
-    public static final Property<Integer> ID2 = Property.create("id2", Integer.class);
-    public static final Property<String> NAME = Property.create("name", String.class);
+    public static final NumericProperty<Integer> ID1 = PropertyFactory.createNumeric("id1", Integer.class);
+    public static final NumericProperty<Integer> ID2 = PropertyFactory.createNumeric("id2", Integer.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+
+    protected Integer id1;
+    protected Integer id2;
+    protected String name;
+
 
     public void setId1(Integer id1) {
-        writeProperty("id1", id1);
+        beforePropertyWrite("id1", this.id1, id1);
+        this.id1 = id1;
     }
+
     public Integer getId1() {
-        return (Integer)readProperty("id1");
+        beforePropertyRead("id1");
+        return this.id1;
     }
 
     public void setId2(Integer id2) {
-        writeProperty("id2", id2);
+        beforePropertyWrite("id2", this.id2, id2);
+        this.id2 = id2;
     }
+
     public Integer getId2() {
-        return (Integer)readProperty("id2");
+        beforePropertyRead("id2");
+        return this.id2;
     }
 
     public void setName(String name) {
-        writeProperty("name", name);
+        beforePropertyWrite("name", this.name, name);
+        this.name = name;
     }
+
     public String getName() {
-        return (String)readProperty("name");
+        beforePropertyRead("name");
+        return this.name;
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "id1":
+                return this.id1;
+            case "id2":
+                return this.id2;
+            case "name":
+                return this.name;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "id1":
+                this.id1 = (Integer)val;
+                break;
+            case "id2":
+                this.id2 = (Integer)val;
+                break;
+            case "name":
+                this.name = (String)val;
+                break;
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+        out.writeObject(this.id1);
+        out.writeObject(this.id2);
+        out.writeObject(this.name);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        super.readState(in);
+        this.id1 = (Integer)in.readObject();
+        this.id2 = (Integer)in.readObject();
+        this.name = (String)in.readObject();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundPkTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundPkTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundPkTestEntity.java
index f067bf9..80f3937 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundPkTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/compound/auto/_CompoundPkTestEntity.java
@@ -6,7 +6,9 @@ import java.io.ObjectOutputStream;
 import java.util.List;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.ListProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.compound.CompoundFkTestEntity;
 
 /**
@@ -22,10 +24,10 @@ public abstract class _CompoundPkTestEntity extends BaseDataObject {
     public static final String KEY1_PK_COLUMN = "KEY1";
     public static final String KEY2_PK_COLUMN = "KEY2";
 
-    public static final Property<String> KEY1 = Property.create("key1", String.class);
-    public static final Property<String> KEY2 = Property.create("key2", String.class);
-    public static final Property<String> NAME = Property.create("name", String.class);
-    public static final Property<List<CompoundFkTestEntity>> COMPOUND_FK_ARRAY = Property.create("compoundFkArray", List.class);
+    public static final StringProperty<String> KEY1 = PropertyFactory.createString("key1", String.class);
+    public static final StringProperty<String> KEY2 = PropertyFactory.createString("key2", String.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+    public static final ListProperty<CompoundFkTestEntity> COMPOUND_FK_ARRAY = PropertyFactory.createList("compoundFkArray", CompoundFkTestEntity.class);
 
     protected String key1;
     protected String key2;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_CalendarEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_CalendarEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_CalendarEntity.java
index fe87795..e474da4 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_CalendarEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_CalendarEntity.java
@@ -6,7 +6,8 @@ import java.io.ObjectOutputStream;
 import java.util.Calendar;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 
 /**
  * Class _CalendarEntity was generated by Cayenne.
@@ -20,7 +21,7 @@ public abstract class _CalendarEntity extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<Calendar> CALENDAR_FIELD = Property.create("calendarField", Calendar.class);
+    public static final BaseProperty<Calendar> CALENDAR_FIELD = PropertyFactory.createBase("calendarField", Calendar.class);
 
     protected Calendar calendarField;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_DateTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_DateTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_DateTestEntity.java
index 222211f..bd7486c 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_DateTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/date_time/auto/_DateTestEntity.java
@@ -6,7 +6,8 @@ import java.io.ObjectOutputStream;
 import java.util.Date;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.DateProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 
 /**
  * Class _DateTestEntity was generated by Cayenne.
@@ -20,9 +21,9 @@ public abstract class _DateTestEntity extends BaseDataObject {
 
     public static final String DATE_TEST_ID_PK_COLUMN = "DATE_TEST_ID";
 
-    public static final Property<Date> DATE_COLUMN = Property.create("dateColumn", Date.class);
-    public static final Property<Date> TIME_COLUMN = Property.create("timeColumn", Date.class);
-    public static final Property<Date> TIMESTAMP_COLUMN = Property.create("timestampColumn", Date.class);
+    public static final DateProperty<Date> DATE_COLUMN = PropertyFactory.createDate("dateColumn", Date.class);
+    public static final DateProperty<Date> TIME_COLUMN = PropertyFactory.createDate("timeColumn", Date.class);
+    public static final DateProperty<Date> TIMESTAMP_COLUMN = PropertyFactory.createDate("timestampColumn", Date.class);
 
     protected Date dateColumn;
     protected Date timeColumn;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToMany.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToMany.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToMany.java
index 289f86e..7451051 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToMany.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToMany.java
@@ -6,7 +6,8 @@ import java.io.ObjectOutputStream;
 import java.util.Map;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.MapProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.testdo.map_to_many.IdMapToManyTarget;
 
 /**
@@ -21,7 +22,7 @@ public abstract class _IdMapToMany extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<Map<Object, IdMapToManyTarget>> TARGETS = Property.create("targets", Map.class);
+    public static final MapProperty<Object, IdMapToManyTarget> TARGETS = PropertyFactory.createMap("targets", Object.class, IdMapToManyTarget.class);
 
 
     protected Object targets;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToManyTarget.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToManyTarget.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToManyTarget.java
index 7c9e69a..f501f3b 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToManyTarget.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_IdMapToManyTarget.java
@@ -5,7 +5,8 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.testdo.map_to_many.IdMapToMany;
 
 /**
@@ -20,7 +21,7 @@ public abstract class _IdMapToManyTarget extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<IdMapToMany> MAP_TO_MANY = Property.create("mapToMany", IdMapToMany.class);
+    public static final EntityProperty<IdMapToMany> MAP_TO_MANY = PropertyFactory.createEntity("mapToMany", IdMapToMany.class);
 
 
     protected Object mapToMany;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToMany.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToMany.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToMany.java
index 731504b..859695e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToMany.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToMany.java
@@ -6,7 +6,8 @@ import java.io.ObjectOutputStream;
 import java.util.Map;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.MapProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.testdo.map_to_many.MapToManyTarget;
 
 /**
@@ -21,7 +22,7 @@ public abstract class _MapToMany extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<Map<String, MapToManyTarget>> TARGETS = Property.create("targets", Map.class);
+    public static final MapProperty<String, MapToManyTarget> TARGETS = PropertyFactory.createMap("targets", String.class, MapToManyTarget.class);
 
 
     protected Object targets;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToManyTarget.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToManyTarget.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToManyTarget.java
index 2ae11ac..2cc2baf 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToManyTarget.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/map_to_many/auto/_MapToManyTarget.java
@@ -5,7 +5,9 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.map_to_many.MapToMany;
 
 /**
@@ -20,8 +22,8 @@ public abstract class _MapToManyTarget extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<String> NAME = Property.create("name", String.class);
-    public static final Property<MapToMany> MAP_TO_MANY = Property.create("mapToMany", MapToMany.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+    public static final EntityProperty<MapToMany> MAP_TO_MANY = PropertyFactory.createEntity("mapToMany", MapToMany.class);
 
     protected String name;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java
index 1493844..05188ae 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java
@@ -5,7 +5,9 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 
 /**
  * Class _PrimitivesTestEntity was generated by Cayenne.
@@ -19,9 +21,9 @@ public abstract class _PrimitivesTestEntity extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<Boolean> BOOLEAN_COLUMN = Property.create("booleanColumn", Boolean.class);
-    public static final Property<Character> CHAR_COLUMN = Property.create("charColumn", Character.class);
-    public static final Property<Integer> INT_COLUMN = Property.create("intColumn", Integer.class);
+    public static final BaseProperty<Boolean> BOOLEAN_COLUMN = PropertyFactory.createBase("booleanColumn", Boolean.class);
+    public static final BaseProperty<Character> CHAR_COLUMN = PropertyFactory.createBase("charColumn", Character.class);
+    public static final NumericProperty<Integer> INT_COLUMN = PropertyFactory.createNumeric("intColumn", Integer.class);
 
     protected Boolean booleanColumn;
     protected Character charColumn;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToMany.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToMany.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToMany.java
index d17f891..f016741 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToMany.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToMany.java
@@ -6,7 +6,8 @@ import java.io.ObjectOutputStream;
 import java.util.Set;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.SetProperty;
 import org.apache.cayenne.testdo.relationships_set_to_many.SetToManyTarget;
 
 /**
@@ -21,7 +22,7 @@ public abstract class _SetToMany extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<Set<SetToManyTarget>> TARGETS = Property.create("targets", Set.class);
+    public static final SetProperty<SetToManyTarget> TARGETS = PropertyFactory.createSet("targets", SetToManyTarget.class);
 
 
     protected Object targets;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToManyTarget.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToManyTarget.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToManyTarget.java
index 59b149b..b603ad1 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToManyTarget.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/relationships_set_to_many/auto/_SetToManyTarget.java
@@ -5,7 +5,8 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.testdo.relationships_set_to_many.SetToMany;
 
 /**
@@ -20,7 +21,7 @@ public abstract class _SetToManyTarget extends BaseDataObject {
 
     public static final String ID_PK_COLUMN = "ID";
 
-    public static final Property<SetToMany> SET_TO_MANY = Property.create("setToMany", SetToMany.class);
+    public static final EntityProperty<SetToMany> SET_TO_MANY = PropertyFactory.createEntity("setToMany", SetToMany.class);
 
 
     protected Object setToMany;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_ArtGroup.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_ArtGroup.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_ArtGroup.java
index a7d48bd..8a19ed8 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_ArtGroup.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_ArtGroup.java
@@ -6,7 +6,12 @@ import java.io.ObjectOutputStream;
 import java.util.List;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.ListProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.testmap.ArtGroup;
 import org.apache.cayenne.testdo.testmap.Artist;
 
@@ -20,12 +25,13 @@ public abstract class _ArtGroup extends BaseDataObject {
 
     private static final long serialVersionUID = 1L; 
 
+    public static final NumericProperty<Integer> GROUP_ID_PK_PROPERTY = PropertyFactory.createNumeric(ExpressionFactory.dbPathExp("GROUP_ID"), Integer.class);
     public static final String GROUP_ID_PK_COLUMN = "GROUP_ID";
 
-    public static final Property<String> NAME = Property.create("name", String.class);
-    public static final Property<List<Artist>> ARTIST_ARRAY = Property.create("artistArray", List.class);
-    public static final Property<List<ArtGroup>> CHILD_GROUPS_ARRAY = Property.create("childGroupsArray", List.class);
-    public static final Property<ArtGroup> TO_PARENT_GROUP = Property.create("toParentGroup", ArtGroup.class);
+    public static final StringProperty<String> NAME = PropertyFactory.createString("name", String.class);
+    public static final ListProperty<Artist> ARTIST_ARRAY = PropertyFactory.createList("artistArray", Artist.class);
+    public static final ListProperty<ArtGroup> CHILD_GROUPS_ARRAY = PropertyFactory.createList("childGroupsArray", ArtGroup.class);
+    public static final EntityProperty<ArtGroup> TO_PARENT_GROUP = PropertyFactory.createEntity("toParentGroup", ArtGroup.class);
 
     protected String name;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/9ea878c0/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Artist.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Artist.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Artist.java
index 26578d0..8c4ea3d 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Artist.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Artist.java
@@ -7,7 +7,12 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.cayenne.BaseDataObject;
-import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.property.DateProperty;
+import org.apache.cayenne.exp.property.ListProperty;
+import org.apache.cayenne.exp.property.NumericProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.StringProperty;
 import org.apache.cayenne.testdo.testmap.ArtGroup;
 import org.apache.cayenne.testdo.testmap.ArtistExhibit;
 import org.apache.cayenne.testdo.testmap.Painting;
@@ -23,12 +28,13 @@ public abstract class _Artist extends BaseDataObject {
     private static final long serialVersionUID = 1L; 
 
     public static final String ARTIST_ID_PK_COLUMN = "ARTIST_ID";
+    public static final NumericProperty<Long> ARTIST_ID_PK_PROPERTY = PropertyFactory.createNumeric(ExpressionFactory.dbPathExp(ARTIST_ID_PK_COLUMN), Long.class);
 
-    public static final Property<String> ARTIST_NAME = Property.create("artistName", String.class);
-    public static final Property<Date> DATE_OF_BIRTH = Property.create("dateOfBirth", Date.class);
-    public static final Property<List<ArtistExhibit>> ARTIST_EXHIBIT_ARRAY = Property.create("artistExhibitArray", List.class);
-    public static final Property<List<ArtGroup>> GROUP_ARRAY = Property.create("groupArray", List.class);
-    public static final Property<List<Painting>> PAINTING_ARRAY = Property.create("paintingArray", List.class);
+    public static final StringProperty<String> ARTIST_NAME = PropertyFactory.createString("artistName", String.class);
+    public static final DateProperty<Date> DATE_OF_BIRTH = PropertyFactory.createDate("dateOfBirth", Date.class);
+    public static final ListProperty<ArtistExhibit> ARTIST_EXHIBIT_ARRAY = PropertyFactory.createList("artistExhibitArray", ArtistExhibit.class);
+    public static final ListProperty<ArtGroup> GROUP_ARRAY = PropertyFactory.createList("groupArray", ArtGroup.class);
+    public static final ListProperty<Painting> PAINTING_ARRAY = PropertyFactory.createList("paintingArray", Painting.class);
 
     protected String artistName;
     protected Date dateOfBirth;


Mime
View raw message