cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject [43/48] Installing Maven Failsafe Plugin
Date Sun, 02 Nov 2014 07:10:31 GMT
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierIT.java b/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierIT.java
new file mode 100644
index 0000000..d0f69eb
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierIT.java
@@ -0,0 +1,240 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.PrefetchTreeNode;
+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.Painting;
+import org.apache.cayenne.unit.di.DataChannelInterceptor;
+import org.apache.cayenne.unit.di.UnitTestClosure;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextMaxIdQualifierIT extends ServerCase {
+
+    @Inject
+    protected DataContext context;
+
+    @Inject
+    protected DBHelper dbHelper;
+
+    @Inject
+    protected DataChannelInterceptor queryInterceptor;
+
+    @Inject
+    protected ServerRuntime runtime;
+    
+    private TableHelper tArtist;
+    private TableHelper tPainting;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("PAINTING_INFO");
+        dbHelper.deleteAll("PAINTING");
+        dbHelper.deleteAll("ARTIST_EXHIBIT");
+        dbHelper.deleteAll("ARTIST_GROUP");
+        dbHelper.deleteAll("ARTIST");
+
+        tArtist = new TableHelper(dbHelper, "ARTIST");
+        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+        tPainting = new TableHelper(dbHelper, "PAINTING");
+        tPainting.setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE").setColumnTypes(Types.INTEGER, Types.BIGINT,
+                Types.VARCHAR);
+    }
+
+    private void insertData() throws SQLException {
+        
+        for (int i = 1; i <= 100; i++) {
+            tArtist.insert(i, "AA" + i);
+            tPainting.insert(i, i, "P" + i);
+        }
+    }
+
+    private void insertData_OneBag_100Boxes() throws SQLException {
+        tArtist.insert(1, "AA1");
+
+        for (int i = 1; i <= 100; i++) {
+            tPainting.insert(i, 1, "P" + i);
+        }
+    }
+
+    public void testDisjointByIdPrefetch() throws Exception {
+        insertData();
+        runtime.getDataDomain().setMaxIdQualifierSize(10);
+        
+        final SelectQuery query = new SelectQuery(Artist.class);
+        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                context.performQuery(query);
+            }
+        });
+
+        assertEquals(11, queriesCount);
+    }
+
+    public void testDisjointByIdPrefetch_Zero() throws Exception {
+        insertData();
+        runtime.getDataDomain().setMaxIdQualifierSize(0);
+
+        final SelectQuery query = new SelectQuery(Artist.class);
+        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                context.performQuery(query);
+            }
+        });
+
+        assertEquals(2, queriesCount);
+    }
+
+    public void testDisjointByIdPrefetch_Negative() throws Exception {
+        insertData();
+        runtime.getDataDomain().setMaxIdQualifierSize(-1);
+
+        final SelectQuery query = new SelectQuery(Artist.class);
+        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                context.performQuery(query);
+            }
+        });
+
+        assertEquals(2, queriesCount);
+    }
+
+    public void testIncrementalFaultList_Lower() throws Exception {
+        insertData_OneBag_100Boxes();
+
+        runtime.getDataDomain().setMaxIdQualifierSize(5);
+
+        final SelectQuery query = new SelectQuery(Painting.class);
+        query.setPageSize(10);
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                for (Painting box : boxes) {
+                    box.getToArtist();
+                }
+            }
+        });
+
+        assertEquals(21, queriesCount);
+
+        queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                List<Painting> tempList = new ArrayList<Painting>();
+                tempList.addAll(boxes);
+            }
+        });
+
+        assertEquals(21, queriesCount);
+    }
+    
+    public void testIncrementalFaultList_Higher() throws Exception {
+        insertData_OneBag_100Boxes();
+
+        runtime.getDataDomain().setMaxIdQualifierSize(101);
+
+        final SelectQuery query = new SelectQuery(Painting.class);
+        query.setPageSize(10);
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                for (Painting box : boxes) {
+                    box.getToArtist();
+                }
+            }
+        });
+
+        assertEquals(11, queriesCount);
+
+        queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                List<Painting> tempList = new ArrayList<Painting>();
+                tempList.addAll(boxes);
+            }
+        });
+
+        assertEquals(2, queriesCount);
+    }
+
+    public void testIncrementalFaultList_Zero() throws Exception {
+        insertData_OneBag_100Boxes();
+
+        runtime.getDataDomain().setMaxIdQualifierSize(0);
+
+        final SelectQuery query = new SelectQuery(Painting.class);
+        query.setPageSize(10);
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                List<Painting> tempList = new ArrayList<Painting>();
+                tempList.addAll(boxes);
+            }
+        });
+
+        assertEquals(2, queriesCount);
+    }
+
+    public void testIncrementalFaultList_Negative() throws Exception {
+        insertData_OneBag_100Boxes();
+
+        runtime.getDataDomain().setMaxIdQualifierSize(-1);
+
+        final SelectQuery query = new SelectQuery(Painting.class);
+        query.setPageSize(10);
+        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
+
+            public void execute() {
+                final List<Painting> boxes = context.performQuery(query);
+                List<Painting> tempList = new ArrayList<Painting>();
+                tempList.addAll(boxes);
+            }
+        });
+
+        assertEquals(2, queriesCount);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierTest.java b/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierTest.java
deleted file mode 100644
index 0606ab2..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/DataContextMaxIdQualifierTest.java
+++ /dev/null
@@ -1,240 +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;
-
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.PrefetchTreeNode;
-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.Painting;
-import org.apache.cayenne.unit.di.DataChannelInterceptor;
-import org.apache.cayenne.unit.di.UnitTestClosure;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class DataContextMaxIdQualifierTest extends ServerCase {
-
-    @Inject
-    protected DataContext context;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    @Inject
-    protected DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    protected ServerRuntime runtime;
-    
-    private TableHelper tArtist;
-    private TableHelper tPainting;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("PAINTING_INFO");
-        dbHelper.deleteAll("PAINTING");
-        dbHelper.deleteAll("ARTIST_EXHIBIT");
-        dbHelper.deleteAll("ARTIST_GROUP");
-        dbHelper.deleteAll("ARTIST");
-
-        tArtist = new TableHelper(dbHelper, "ARTIST");
-        tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
-        tPainting = new TableHelper(dbHelper, "PAINTING");
-        tPainting.setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE").setColumnTypes(Types.INTEGER, Types.BIGINT,
-                Types.VARCHAR);
-    }
-
-    private void insertData() throws SQLException {
-        
-        for (int i = 1; i <= 100; i++) {
-            tArtist.insert(i, "AA" + i);
-            tPainting.insert(i, i, "P" + i);
-        }
-    }
-
-    private void insertData_OneBag_100Boxes() throws SQLException {
-        tArtist.insert(1, "AA1");
-
-        for (int i = 1; i <= 100; i++) {
-            tPainting.insert(i, 1, "P" + i);
-        }
-    }
-
-    public void testDisjointByIdPrefetch() throws Exception {
-        insertData();
-        runtime.getDataDomain().setMaxIdQualifierSize(10);
-        
-        final SelectQuery query = new SelectQuery(Artist.class);
-        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
-
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                context.performQuery(query);
-            }
-        });
-
-        assertEquals(11, queriesCount);
-    }
-
-    public void testDisjointByIdPrefetch_Zero() throws Exception {
-        insertData();
-        runtime.getDataDomain().setMaxIdQualifierSize(0);
-
-        final SelectQuery query = new SelectQuery(Artist.class);
-        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
-
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                context.performQuery(query);
-            }
-        });
-
-        assertEquals(2, queriesCount);
-    }
-
-    public void testDisjointByIdPrefetch_Negative() throws Exception {
-        insertData();
-        runtime.getDataDomain().setMaxIdQualifierSize(-1);
-
-        final SelectQuery query = new SelectQuery(Artist.class);
-        query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
-
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                context.performQuery(query);
-            }
-        });
-
-        assertEquals(2, queriesCount);
-    }
-
-    public void testIncrementalFaultList_Lower() throws Exception {
-        insertData_OneBag_100Boxes();
-
-        runtime.getDataDomain().setMaxIdQualifierSize(5);
-
-        final SelectQuery query = new SelectQuery(Painting.class);
-        query.setPageSize(10);
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                for (Painting box : boxes) {
-                    box.getToArtist();
-                }
-            }
-        });
-
-        assertEquals(21, queriesCount);
-
-        queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                List<Painting> tempList = new ArrayList<Painting>();
-                tempList.addAll(boxes);
-            }
-        });
-
-        assertEquals(21, queriesCount);
-    }
-    
-    public void testIncrementalFaultList_Higher() throws Exception {
-        insertData_OneBag_100Boxes();
-
-        runtime.getDataDomain().setMaxIdQualifierSize(101);
-
-        final SelectQuery query = new SelectQuery(Painting.class);
-        query.setPageSize(10);
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                for (Painting box : boxes) {
-                    box.getToArtist();
-                }
-            }
-        });
-
-        assertEquals(11, queriesCount);
-
-        queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                List<Painting> tempList = new ArrayList<Painting>();
-                tempList.addAll(boxes);
-            }
-        });
-
-        assertEquals(2, queriesCount);
-    }
-
-    public void testIncrementalFaultList_Zero() throws Exception {
-        insertData_OneBag_100Boxes();
-
-        runtime.getDataDomain().setMaxIdQualifierSize(0);
-
-        final SelectQuery query = new SelectQuery(Painting.class);
-        query.setPageSize(10);
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                List<Painting> tempList = new ArrayList<Painting>();
-                tempList.addAll(boxes);
-            }
-        });
-
-        assertEquals(2, queriesCount);
-    }
-
-    public void testIncrementalFaultList_Negative() throws Exception {
-        insertData_OneBag_100Boxes();
-
-        runtime.getDataDomain().setMaxIdQualifierSize(-1);
-
-        final SelectQuery query = new SelectQuery(Painting.class);
-        query.setPageSize(10);
-        int queriesCount = queryInterceptor.runWithQueryCounter(new UnitTestClosure() {
-
-            public void execute() {
-                final List<Painting> boxes = context.performQuery(query);
-                List<Painting> tempList = new ArrayList<Painting>();
-                tempList.addAll(boxes);
-            }
-        });
-
-        assertEquals(2, queriesCount);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java b/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java
new file mode 100644
index 0000000..13c4228
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java
@@ -0,0 +1,119 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.access.ToManyList;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.Util;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataObjectSerializationIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    public void testSerializeTransient() throws Exception {
+        Artist artist = new Artist();
+        artist.setArtistName("artist1");
+        assertEquals(PersistenceState.TRANSIENT, artist.getPersistenceState());
+        assertNull(artist.getObjectId());
+
+        Artist deserialized = Util.cloneViaSerialization(artist);
+        assertEquals(PersistenceState.TRANSIENT, deserialized.getPersistenceState());
+        assertNull(deserialized.getObjectId());
+        assertEquals("artist1", deserialized.getArtistName());
+    }
+
+    public void testSerializeNew() throws Exception {
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("artist1");
+        // resolve relationship fault
+        artist.getPaintingArray();
+
+        Artist deserialized = Util.cloneViaSerialization(artist);
+
+        // everything must be deserialized, but DataContext link should stay null
+        assertEquals(PersistenceState.NEW, deserialized.getPersistenceState());
+        assertTrue(deserialized.getObjectId().isTemporary());
+        assertEquals("artist1", deserialized.getArtistName());
+
+        assertNull("CDO serialized by itself shouldn't have a DataContext: "
+                + deserialized.getObjectContext(), deserialized.getObjectContext());
+
+        // test that to-many relationships are initialized
+        List<?> paintings = deserialized.getPaintingArray();
+        assertNotNull(paintings);
+        assertEquals(0, paintings.size());
+    }
+
+    public void testSerializeNewWithFaults() throws Exception {
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("artist1");
+
+        Artist deserialized = Util.cloneViaSerialization(artist);
+
+        // everything must be deserialized, but DataContext link should stay null
+        assertEquals(PersistenceState.NEW, deserialized.getPersistenceState());
+        assertTrue(deserialized.getObjectId().isTemporary());
+        assertEquals("artist1", deserialized.getArtistName());
+
+        assertNull("CDO serialized by itself shouldn't have a DataContext: "
+                + deserialized.getObjectContext(), deserialized.getObjectContext());
+
+        // test that to-many relationships are initialized
+        assertTrue(deserialized.readPropertyDirectly("paintingArray") instanceof ToManyList);
+        ToManyList list = (ToManyList) artist.readPropertyDirectly("paintingArray");
+        assertFalse(list.isFault());
+    }
+
+    public void testSerializeCommitted() throws Exception {
+
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("artist1");
+        context.commitChanges();
+
+        assertEquals(PersistenceState.COMMITTED, artist.getPersistenceState());
+
+        ObjectId id = artist.getObjectId();
+        assertNotNull(id);
+
+        Artist deserialized = Util.cloneViaSerialization(artist);
+
+        // everything must be deserialized, but DataContext link should stay null,
+        // and properties shouldn't be populated
+        // deserizalized committed object is HOLLOW
+        assertEquals("Unexpected persistence state: "
+                + PersistenceState.persistenceStateName(deserialized
+                        .getPersistenceState()), PersistenceState.HOLLOW, deserialized
+                .getPersistenceState());
+
+        assertEquals(id, deserialized.getObjectId());
+
+        // properties of committed objects are not set...when DataContext is
+        // attached to an object, object can populate itself from snapshot
+        assertNull(deserialized.getObjectContext());
+        assertEquals(null, deserialized.getArtistName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationTest.java b/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationTest.java
deleted file mode 100644
index de427bf..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationTest.java
+++ /dev/null
@@ -1,119 +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;
-
-import java.util.List;
-
-import org.apache.cayenne.access.ToManyList;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.Util;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class DataObjectSerializationTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-
-    public void testSerializeTransient() throws Exception {
-        Artist artist = new Artist();
-        artist.setArtistName("artist1");
-        assertEquals(PersistenceState.TRANSIENT, artist.getPersistenceState());
-        assertNull(artist.getObjectId());
-
-        Artist deserialized = Util.cloneViaSerialization(artist);
-        assertEquals(PersistenceState.TRANSIENT, deserialized.getPersistenceState());
-        assertNull(deserialized.getObjectId());
-        assertEquals("artist1", deserialized.getArtistName());
-    }
-
-    public void testSerializeNew() throws Exception {
-        Artist artist = context.newObject(Artist.class);
-        artist.setArtistName("artist1");
-        // resolve relationship fault
-        artist.getPaintingArray();
-
-        Artist deserialized = Util.cloneViaSerialization(artist);
-
-        // everything must be deserialized, but DataContext link should stay null
-        assertEquals(PersistenceState.NEW, deserialized.getPersistenceState());
-        assertTrue(deserialized.getObjectId().isTemporary());
-        assertEquals("artist1", deserialized.getArtistName());
-
-        assertNull("CDO serialized by itself shouldn't have a DataContext: "
-                + deserialized.getObjectContext(), deserialized.getObjectContext());
-
-        // test that to-many relationships are initialized
-        List<?> paintings = deserialized.getPaintingArray();
-        assertNotNull(paintings);
-        assertEquals(0, paintings.size());
-    }
-
-    public void testSerializeNewWithFaults() throws Exception {
-        Artist artist = context.newObject(Artist.class);
-        artist.setArtistName("artist1");
-
-        Artist deserialized = Util.cloneViaSerialization(artist);
-
-        // everything must be deserialized, but DataContext link should stay null
-        assertEquals(PersistenceState.NEW, deserialized.getPersistenceState());
-        assertTrue(deserialized.getObjectId().isTemporary());
-        assertEquals("artist1", deserialized.getArtistName());
-
-        assertNull("CDO serialized by itself shouldn't have a DataContext: "
-                + deserialized.getObjectContext(), deserialized.getObjectContext());
-
-        // test that to-many relationships are initialized
-        assertTrue(deserialized.readPropertyDirectly("paintingArray") instanceof ToManyList);
-        ToManyList list = (ToManyList) artist.readPropertyDirectly("paintingArray");
-        assertFalse(list.isFault());
-    }
-
-    public void testSerializeCommitted() throws Exception {
-
-        Artist artist = context.newObject(Artist.class);
-        artist.setArtistName("artist1");
-        context.commitChanges();
-
-        assertEquals(PersistenceState.COMMITTED, artist.getPersistenceState());
-
-        ObjectId id = artist.getObjectId();
-        assertNotNull(id);
-
-        Artist deserialized = Util.cloneViaSerialization(artist);
-
-        // everything must be deserialized, but DataContext link should stay null,
-        // and properties shouldn't be populated
-        // deserizalized committed object is HOLLOW
-        assertEquals("Unexpected persistence state: "
-                + PersistenceState.persistenceStateName(deserialized
-                        .getPersistenceState()), PersistenceState.HOLLOW, deserialized
-                .getPersistenceState());
-
-        assertEquals(id, deserialized.getObjectId());
-
-        // properties of committed objects are not set...when DataContext is
-        // attached to an object, object can populate itself from snapshot
-        assertNull(deserialized.getObjectContext());
-        assertEquals(null, deserialized.getArtistName());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsIT.java
new file mode 100644
index 0000000..b38937c
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsIT.java
@@ -0,0 +1,287 @@
+/*****************************************************************
+ *   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;
+
+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.query.SQLTemplate;
+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.relationship.FlattenedCircular;
+import org.apache.cayenne.testdo.relationship.FlattenedTest1;
+import org.apache.cayenne.testdo.relationship.FlattenedTest2;
+import org.apache.cayenne.testdo.relationship.FlattenedTest3;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+/**
+ * Test case for objects with flattened relationships.
+ */
+@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
+public class FlattenedRelationshipsIT extends ServerCase {
+
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DataContext context1;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tFlattenedTest1;
+    private TableHelper tFlattenedTest2;
+    private TableHelper tFlattenedTest3;
+    private TableHelper tComplexJoin;
+    private TableHelper tFlattenedCircular;
+    private TableHelper tFlattenedCircularJoin;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("COMPLEX_JOIN");
+        dbHelper.deleteAll("FLATTENED_TEST_4");
+        dbHelper.deleteAll("FLATTENED_TEST_3");
+        dbHelper.deleteAll("FLATTENED_TEST_2");
+        dbHelper.deleteAll("FLATTENED_TEST_1");
+        dbHelper.deleteAll("FLATTENED_CIRCULAR_JOIN");
+        dbHelper.deleteAll("FLATTENED_CIRCULAR");
+
+        tFlattenedTest1 = new TableHelper(dbHelper, "FLATTENED_TEST_1");
+        tFlattenedTest1.setColumns("FT1_ID", "NAME");
+
+        tFlattenedTest2 = new TableHelper(dbHelper, "FLATTENED_TEST_2");
+        tFlattenedTest2.setColumns("FT2_ID", "FT1_ID", "NAME");
+
+        tFlattenedTest3 = new TableHelper(dbHelper, "FLATTENED_TEST_3");
+        tFlattenedTest3.setColumns("FT3_ID", "FT2_ID", "NAME").setColumnTypes(
+                Types.INTEGER, Types.INTEGER, Types.VARCHAR);
+
+        tComplexJoin = new TableHelper(dbHelper, "COMPLEX_JOIN");
+        tComplexJoin.setColumns("PK", "FT1_FK", "FT3_FK", "EXTRA_COLUMN");
+
+        tFlattenedCircular = new TableHelper(dbHelper, "FLATTENED_CIRCULAR");
+        tFlattenedCircular.setColumns("ID");
+
+        tFlattenedCircularJoin = new TableHelper(dbHelper, "FLATTENED_CIRCULAR_JOIN");
+        tFlattenedCircularJoin.setColumns("SIDE1_ID", "SIDE2_ID");
+    }
+
+    protected void createFlattenedTestDataSet() throws Exception {
+        tFlattenedTest1.insert(1, "ft1");
+        tFlattenedTest1.insert(2, "ft12");
+        tFlattenedTest2.insert(1, 1, "ft2");
+        tFlattenedTest3.insert(1, 1, "ft3");
+    }
+
+    protected void createFlattenedCircularDataSet() throws Exception {
+        tFlattenedCircular.insert(1);
+        tFlattenedCircular.insert(2);
+        tFlattenedCircular.insert(3);
+        tFlattenedCircularJoin.insert(1, 2);
+        tFlattenedCircularJoin.insert(1, 3);
+    }
+
+    protected void createCircularJoinDataSet() throws Exception {
+        tFlattenedTest1.insert(2, "ft12");
+        tFlattenedTest3.insert(2, null, "ft3-a");
+        tFlattenedTest3.insert(3, null, "ft3-b");
+        tComplexJoin.insert(2000, 2, 2, "A");
+        tComplexJoin.insert(2001, 2, 3, "B");
+        tComplexJoin.insert(2002, 2, 3, "C");
+    }
+
+    public void testInsertJoinWithPK() throws Exception {
+        FlattenedTest1 obj01 = context.newObject(FlattenedTest1.class);
+        FlattenedTest3 obj11 = context.newObject(FlattenedTest3.class);
+        FlattenedTest3 obj12 = context.newObject(FlattenedTest3.class);
+
+        obj01.setName("t01");
+        obj11.setName("t11");
+        obj12.setName("t12");
+
+        obj01.addToFt3OverComplex(obj11);
+        obj01.addToFt3OverComplex(obj12);
+
+        context.commitChanges();
+
+        int pk = Cayenne.intPKForObject(obj01);
+
+        context.invalidateObjects(obj01, obj11, obj12);
+
+        FlattenedTest1 fresh01 = Cayenne.objectForPK(context1, FlattenedTest1.class, pk);
+
+        assertEquals("t01", fresh01.getName());
+        ValueHolder related = (ValueHolder) fresh01.getFt3OverComplex();
+        assertTrue(related.isFault());
+
+        assertEquals(2, ((List<?>) related).size());
+    }
+
+    public void testUnsetJoinWithPK() throws Exception {
+        createCircularJoinDataSet();
+
+        SQLTemplate joinSelect = new SQLTemplate(
+                FlattenedTest1.class,
+                "SELECT * FROM COMPLEX_JOIN");
+        joinSelect.setFetchingDataRows(true);
+        assertEquals(3, context.performQuery(joinSelect).size());
+
+        FlattenedTest1 ft1 = Cayenne.objectForPK(context, FlattenedTest1.class, 2);
+
+        assertEquals("ft12", ft1.getName());
+        List<FlattenedTest3> related = ft1.getFt3OverComplex();
+        assertTrue(((ValueHolder) related).isFault());
+
+        assertEquals(2, related.size());
+
+        FlattenedTest3 ft3 = Cayenne.objectForPK(context, FlattenedTest3.class, 3);
+        assertTrue(related.contains(ft3));
+
+        ft1.removeFromFt3OverComplex(ft3);
+        assertFalse(related.contains(ft3));
+        context.commitChanges();
+
+        // the thing here is that there are two join records between
+        // FT1 and FT3 (emulating invalid data or extras in the join table that
+        // are ignored in the object model).. all (2) joins must be deleted
+        assertEquals(1, context.performQuery(joinSelect).size());
+    }
+
+    public void testQualifyOnToManyFlattened() throws Exception {
+        FlattenedTest1 obj01 = context.newObject(FlattenedTest1.class);
+        FlattenedTest2 obj02 = context.newObject(FlattenedTest2.class);
+        FlattenedTest3 obj031 = context.newObject(FlattenedTest3.class);
+        FlattenedTest3 obj032 = context.newObject(FlattenedTest3.class);
+
+        FlattenedTest1 obj11 = context.newObject(FlattenedTest1.class);
+        FlattenedTest2 obj12 = context.newObject(FlattenedTest2.class);
+        FlattenedTest3 obj131 = context.newObject(FlattenedTest3.class);
+
+        obj01.setName("t01");
+        obj02.setName("t02");
+        obj031.setName("t031");
+        obj032.setName("t032");
+        obj02.setToFT1(obj01);
+        obj02.addToFt3Array(obj031);
+        obj02.addToFt3Array(obj032);
+
+        obj11.setName("t11");
+        obj131.setName("t131");
+        obj12.setName("t12");
+        obj12.addToFt3Array(obj131);
+        obj12.setToFT1(obj11);
+
+        context.commitChanges();
+
+        // test 1: qualify on flattened attribute
+        Expression qual1 = ExpressionFactory.matchExp("ft3Array.name", "t031");
+        SelectQuery query1 = new SelectQuery(FlattenedTest1.class, qual1);
+        List<?> objects1 = context.performQuery(query1);
+
+        assertEquals(1, objects1.size());
+        assertSame(obj01, objects1.get(0));
+
+        // test 2: qualify on flattened relationship
+        Expression qual2 = ExpressionFactory.matchExp("ft3Array", obj131);
+        SelectQuery query2 = new SelectQuery(FlattenedTest1.class, qual2);
+        List<?> objects2 = context.performQuery(query2);
+
+        assertEquals(1, objects2.size());
+        assertSame(obj11, objects2.get(0));
+    }
+
+    public void testToOneSeriesFlattenedRel() {
+
+        FlattenedTest1 ft1 = (FlattenedTest1) context.newObject("FlattenedTest1");
+        ft1.setName("FT1Name");
+        FlattenedTest2 ft2 = (FlattenedTest2) context.newObject("FlattenedTest2");
+        ft2.setName("FT2Name");
+        FlattenedTest3 ft3 = (FlattenedTest3) context.newObject("FlattenedTest3");
+        ft3.setName("FT3Name");
+
+        ft2.setToFT1(ft1);
+        ft2.addToFt3Array(ft3);
+        context.commitChanges();
+
+        context.invalidateObjects(ft1, ft2, ft3);
+
+        SelectQuery q = new SelectQuery(FlattenedTest3.class);
+        q.setQualifier(ExpressionFactory.matchExp("name", "FT3Name"));
+        List<?> results = context1.performQuery(q);
+
+        assertEquals(1, results.size());
+
+        FlattenedTest3 fetchedFT3 = (FlattenedTest3) results.get(0);
+        FlattenedTest1 fetchedFT1 = fetchedFT3.getToFT1();
+        assertEquals("FT1Name", fetchedFT1.getName());
+    }
+
+    public void testTakeObjectSnapshotFlattenedFault() throws Exception {
+        createFlattenedTestDataSet();
+
+        // fetch
+        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
+        assertEquals(1, ft3s.size());
+        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
+
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+
+        // test that taking a snapshot does not trigger a fault, and generally works well
+        DataRow snapshot = context.currentSnapshot(ft3);
+
+        assertEquals("ft3", snapshot.get("NAME"));
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+
+    }
+
+    public void testRefetchWithFlattenedFaultToOneTarget1() throws Exception {
+        createFlattenedTestDataSet();
+
+        // fetch
+        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
+        assertEquals(1, ft3s.size());
+        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
+
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+
+        // refetch
+        context.performQuery(new SelectQuery(FlattenedTest3.class));
+        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
+    }
+
+    public void testFlattenedCircular() throws Exception {
+        createFlattenedCircularDataSet();
+
+        FlattenedCircular fc1 = Cayenne.objectForPK(context, FlattenedCircular.class, 1);
+
+        List<FlattenedCircular> side2s = fc1.getSide2s();
+        assertEquals(2, side2s.size());
+
+        List<FlattenedCircular> side1s = fc1.getSide1s();
+        assertTrue(side1s.isEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsTest.java b/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsTest.java
deleted file mode 100644
index e5eb504..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/FlattenedRelationshipsTest.java
+++ /dev/null
@@ -1,287 +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;
-
-import java.sql.Types;
-import java.util.List;
-
-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.query.SQLTemplate;
-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.relationship.FlattenedCircular;
-import org.apache.cayenne.testdo.relationship.FlattenedTest1;
-import org.apache.cayenne.testdo.relationship.FlattenedTest2;
-import org.apache.cayenne.testdo.relationship.FlattenedTest3;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * Test case for objects with flattened relationships.
- */
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class FlattenedRelationshipsTest extends ServerCase {
-
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DataContext context1;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tFlattenedTest1;
-    private TableHelper tFlattenedTest2;
-    private TableHelper tFlattenedTest3;
-    private TableHelper tComplexJoin;
-    private TableHelper tFlattenedCircular;
-    private TableHelper tFlattenedCircularJoin;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("COMPLEX_JOIN");
-        dbHelper.deleteAll("FLATTENED_TEST_4");
-        dbHelper.deleteAll("FLATTENED_TEST_3");
-        dbHelper.deleteAll("FLATTENED_TEST_2");
-        dbHelper.deleteAll("FLATTENED_TEST_1");
-        dbHelper.deleteAll("FLATTENED_CIRCULAR_JOIN");
-        dbHelper.deleteAll("FLATTENED_CIRCULAR");
-
-        tFlattenedTest1 = new TableHelper(dbHelper, "FLATTENED_TEST_1");
-        tFlattenedTest1.setColumns("FT1_ID", "NAME");
-
-        tFlattenedTest2 = new TableHelper(dbHelper, "FLATTENED_TEST_2");
-        tFlattenedTest2.setColumns("FT2_ID", "FT1_ID", "NAME");
-
-        tFlattenedTest3 = new TableHelper(dbHelper, "FLATTENED_TEST_3");
-        tFlattenedTest3.setColumns("FT3_ID", "FT2_ID", "NAME").setColumnTypes(
-                Types.INTEGER, Types.INTEGER, Types.VARCHAR);
-
-        tComplexJoin = new TableHelper(dbHelper, "COMPLEX_JOIN");
-        tComplexJoin.setColumns("PK", "FT1_FK", "FT3_FK", "EXTRA_COLUMN");
-
-        tFlattenedCircular = new TableHelper(dbHelper, "FLATTENED_CIRCULAR");
-        tFlattenedCircular.setColumns("ID");
-
-        tFlattenedCircularJoin = new TableHelper(dbHelper, "FLATTENED_CIRCULAR_JOIN");
-        tFlattenedCircularJoin.setColumns("SIDE1_ID", "SIDE2_ID");
-    }
-
-    protected void createFlattenedTestDataSet() throws Exception {
-        tFlattenedTest1.insert(1, "ft1");
-        tFlattenedTest1.insert(2, "ft12");
-        tFlattenedTest2.insert(1, 1, "ft2");
-        tFlattenedTest3.insert(1, 1, "ft3");
-    }
-
-    protected void createFlattenedCircularDataSet() throws Exception {
-        tFlattenedCircular.insert(1);
-        tFlattenedCircular.insert(2);
-        tFlattenedCircular.insert(3);
-        tFlattenedCircularJoin.insert(1, 2);
-        tFlattenedCircularJoin.insert(1, 3);
-    }
-
-    protected void createCircularJoinDataSet() throws Exception {
-        tFlattenedTest1.insert(2, "ft12");
-        tFlattenedTest3.insert(2, null, "ft3-a");
-        tFlattenedTest3.insert(3, null, "ft3-b");
-        tComplexJoin.insert(2000, 2, 2, "A");
-        tComplexJoin.insert(2001, 2, 3, "B");
-        tComplexJoin.insert(2002, 2, 3, "C");
-    }
-
-    public void testInsertJoinWithPK() throws Exception {
-        FlattenedTest1 obj01 = context.newObject(FlattenedTest1.class);
-        FlattenedTest3 obj11 = context.newObject(FlattenedTest3.class);
-        FlattenedTest3 obj12 = context.newObject(FlattenedTest3.class);
-
-        obj01.setName("t01");
-        obj11.setName("t11");
-        obj12.setName("t12");
-
-        obj01.addToFt3OverComplex(obj11);
-        obj01.addToFt3OverComplex(obj12);
-
-        context.commitChanges();
-
-        int pk = Cayenne.intPKForObject(obj01);
-
-        context.invalidateObjects(obj01, obj11, obj12);
-
-        FlattenedTest1 fresh01 = Cayenne.objectForPK(context1, FlattenedTest1.class, pk);
-
-        assertEquals("t01", fresh01.getName());
-        ValueHolder related = (ValueHolder) fresh01.getFt3OverComplex();
-        assertTrue(related.isFault());
-
-        assertEquals(2, ((List<?>) related).size());
-    }
-
-    public void testUnsetJoinWithPK() throws Exception {
-        createCircularJoinDataSet();
-
-        SQLTemplate joinSelect = new SQLTemplate(
-                FlattenedTest1.class,
-                "SELECT * FROM COMPLEX_JOIN");
-        joinSelect.setFetchingDataRows(true);
-        assertEquals(3, context.performQuery(joinSelect).size());
-
-        FlattenedTest1 ft1 = Cayenne.objectForPK(context, FlattenedTest1.class, 2);
-
-        assertEquals("ft12", ft1.getName());
-        List<FlattenedTest3> related = ft1.getFt3OverComplex();
-        assertTrue(((ValueHolder) related).isFault());
-
-        assertEquals(2, related.size());
-
-        FlattenedTest3 ft3 = Cayenne.objectForPK(context, FlattenedTest3.class, 3);
-        assertTrue(related.contains(ft3));
-
-        ft1.removeFromFt3OverComplex(ft3);
-        assertFalse(related.contains(ft3));
-        context.commitChanges();
-
-        // the thing here is that there are two join records between
-        // FT1 and FT3 (emulating invalid data or extras in the join table that
-        // are ignored in the object model).. all (2) joins must be deleted
-        assertEquals(1, context.performQuery(joinSelect).size());
-    }
-
-    public void testQualifyOnToManyFlattened() throws Exception {
-        FlattenedTest1 obj01 = context.newObject(FlattenedTest1.class);
-        FlattenedTest2 obj02 = context.newObject(FlattenedTest2.class);
-        FlattenedTest3 obj031 = context.newObject(FlattenedTest3.class);
-        FlattenedTest3 obj032 = context.newObject(FlattenedTest3.class);
-
-        FlattenedTest1 obj11 = context.newObject(FlattenedTest1.class);
-        FlattenedTest2 obj12 = context.newObject(FlattenedTest2.class);
-        FlattenedTest3 obj131 = context.newObject(FlattenedTest3.class);
-
-        obj01.setName("t01");
-        obj02.setName("t02");
-        obj031.setName("t031");
-        obj032.setName("t032");
-        obj02.setToFT1(obj01);
-        obj02.addToFt3Array(obj031);
-        obj02.addToFt3Array(obj032);
-
-        obj11.setName("t11");
-        obj131.setName("t131");
-        obj12.setName("t12");
-        obj12.addToFt3Array(obj131);
-        obj12.setToFT1(obj11);
-
-        context.commitChanges();
-
-        // test 1: qualify on flattened attribute
-        Expression qual1 = ExpressionFactory.matchExp("ft3Array.name", "t031");
-        SelectQuery query1 = new SelectQuery(FlattenedTest1.class, qual1);
-        List<?> objects1 = context.performQuery(query1);
-
-        assertEquals(1, objects1.size());
-        assertSame(obj01, objects1.get(0));
-
-        // test 2: qualify on flattened relationship
-        Expression qual2 = ExpressionFactory.matchExp("ft3Array", obj131);
-        SelectQuery query2 = new SelectQuery(FlattenedTest1.class, qual2);
-        List<?> objects2 = context.performQuery(query2);
-
-        assertEquals(1, objects2.size());
-        assertSame(obj11, objects2.get(0));
-    }
-
-    public void testToOneSeriesFlattenedRel() {
-
-        FlattenedTest1 ft1 = (FlattenedTest1) context.newObject("FlattenedTest1");
-        ft1.setName("FT1Name");
-        FlattenedTest2 ft2 = (FlattenedTest2) context.newObject("FlattenedTest2");
-        ft2.setName("FT2Name");
-        FlattenedTest3 ft3 = (FlattenedTest3) context.newObject("FlattenedTest3");
-        ft3.setName("FT3Name");
-
-        ft2.setToFT1(ft1);
-        ft2.addToFt3Array(ft3);
-        context.commitChanges();
-
-        context.invalidateObjects(ft1, ft2, ft3);
-
-        SelectQuery q = new SelectQuery(FlattenedTest3.class);
-        q.setQualifier(ExpressionFactory.matchExp("name", "FT3Name"));
-        List<?> results = context1.performQuery(q);
-
-        assertEquals(1, results.size());
-
-        FlattenedTest3 fetchedFT3 = (FlattenedTest3) results.get(0);
-        FlattenedTest1 fetchedFT1 = fetchedFT3.getToFT1();
-        assertEquals("FT1Name", fetchedFT1.getName());
-    }
-
-    public void testTakeObjectSnapshotFlattenedFault() throws Exception {
-        createFlattenedTestDataSet();
-
-        // fetch
-        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
-        assertEquals(1, ft3s.size());
-        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
-
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-
-        // test that taking a snapshot does not trigger a fault, and generally works well
-        DataRow snapshot = context.currentSnapshot(ft3);
-
-        assertEquals("ft3", snapshot.get("NAME"));
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-
-    }
-
-    public void testRefetchWithFlattenedFaultToOneTarget1() throws Exception {
-        createFlattenedTestDataSet();
-
-        // fetch
-        List<?> ft3s = context.performQuery(new SelectQuery(FlattenedTest3.class));
-        assertEquals(1, ft3s.size());
-        FlattenedTest3 ft3 = (FlattenedTest3) ft3s.get(0);
-
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-
-        // refetch
-        context.performQuery(new SelectQuery(FlattenedTest3.class));
-        assertTrue(ft3.readPropertyDirectly("toFT1") instanceof Fault);
-    }
-
-    public void testFlattenedCircular() throws Exception {
-        createFlattenedCircularDataSet();
-
-        FlattenedCircular fc1 = Cayenne.objectForPK(context, FlattenedCircular.class, 1);
-
-        List<FlattenedCircular> side2s = fc1.getSide2s();
-        assertEquals(2, side2s.size());
-
-        List<FlattenedCircular> side1s = fc1.getSide1s();
-        assertTrue(side1s.isEmpty());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingIT.java b/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingIT.java
new file mode 100644
index 0000000..c7bae44
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingIT.java
@@ -0,0 +1,110 @@
+/*****************************************************************
+ *   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;
+
+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.query.SQLTemplate;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.DEFAULT_PROJECT)
+public class GenericMappingIT extends ServerCase {
+
+    @Inject
+    private DataContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("GENERIC2");
+        dbHelper.deleteAll("GENERIC1");
+    }
+
+    public void testInsertSingle() {
+        DataObject g1 = (DataObject) context.newObject("Generic1");
+        g1.writeProperty("name", "G1 Name");
+
+        context.commitChanges();
+    }
+
+    public void testInsertRelated() {
+        DataObject g1 = (DataObject) context.newObject("Generic1");
+        g1.writeProperty("name", "G1 Name");
+
+        DataObject g2 = (DataObject) context.newObject("Generic2");
+        g2.writeProperty("name", "G2 Name");
+        g2.setToOneTarget("toGeneric1", g1, true);
+
+        context.commitChanges();
+    }
+
+    public void testSelect() {
+        context.performNonSelectingQuery(new SQLTemplate(
+                "Generic1",
+                "INSERT INTO GENERIC1 (ID, NAME) VALUES (1, 'AAAA')"));
+        context.performNonSelectingQuery(new SQLTemplate(
+                "Generic1",
+                "INSERT INTO GENERIC1 (ID, NAME) VALUES (2, 'BBBB')"));
+        context.performNonSelectingQuery(new SQLTemplate(
+                "Generic1",
+                "INSERT INTO GENERIC2 (GENERIC1_ID, ID, NAME) VALUES (1, 1, 'CCCCC')"));
+
+        Expression qual = ExpressionFactory.matchExp("name", "AAAA");
+        SelectQuery q = new SelectQuery("Generic1", qual);
+
+        List<?> result = context.performQuery(q);
+        assertEquals(1, result.size());
+    }
+
+    public void testUpdateRelated() {
+        DataObject g1 = (DataObject) context.newObject("Generic1");
+        g1.writeProperty("name", "G1 Name");
+
+        DataObject g2 = (DataObject) context.newObject("Generic2");
+        g2.writeProperty("name", "G2 Name");
+        g2.setToOneTarget("toGeneric1", g1, true);
+
+        context.commitChanges();
+
+        List<?> r1 = (List<?>) g1.readProperty("generic2s");
+        assertTrue(r1.contains(g2));
+
+        DataObject g11 = (DataObject) context.newObject("Generic1");
+        g11.writeProperty("name", "G11 Name");
+        g2.setToOneTarget("toGeneric1", g11, true);
+
+        context.commitChanges();
+
+        List<?> r11 = (List<?>) g11.readProperty("generic2s");
+        assertTrue(r11.contains(g2));
+
+        List<?> r1_1 = (List<?>) g1.readProperty("generic2s");
+        assertFalse(r1_1.contains(g2));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingTest.java b/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingTest.java
deleted file mode 100644
index 852f990..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/GenericMappingTest.java
+++ /dev/null
@@ -1,110 +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;
-
-import java.util.List;
-
-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.query.SQLTemplate;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.DEFAULT_PROJECT)
-public class GenericMappingTest extends ServerCase {
-
-    @Inject
-    private DataContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("GENERIC2");
-        dbHelper.deleteAll("GENERIC1");
-    }
-
-    public void testInsertSingle() {
-        DataObject g1 = (DataObject) context.newObject("Generic1");
-        g1.writeProperty("name", "G1 Name");
-
-        context.commitChanges();
-    }
-
-    public void testInsertRelated() {
-        DataObject g1 = (DataObject) context.newObject("Generic1");
-        g1.writeProperty("name", "G1 Name");
-
-        DataObject g2 = (DataObject) context.newObject("Generic2");
-        g2.writeProperty("name", "G2 Name");
-        g2.setToOneTarget("toGeneric1", g1, true);
-
-        context.commitChanges();
-    }
-
-    public void testSelect() {
-        context.performNonSelectingQuery(new SQLTemplate(
-                "Generic1",
-                "INSERT INTO GENERIC1 (ID, NAME) VALUES (1, 'AAAA')"));
-        context.performNonSelectingQuery(new SQLTemplate(
-                "Generic1",
-                "INSERT INTO GENERIC1 (ID, NAME) VALUES (2, 'BBBB')"));
-        context.performNonSelectingQuery(new SQLTemplate(
-                "Generic1",
-                "INSERT INTO GENERIC2 (GENERIC1_ID, ID, NAME) VALUES (1, 1, 'CCCCC')"));
-
-        Expression qual = ExpressionFactory.matchExp("name", "AAAA");
-        SelectQuery q = new SelectQuery("Generic1", qual);
-
-        List<?> result = context.performQuery(q);
-        assertEquals(1, result.size());
-    }
-
-    public void testUpdateRelated() {
-        DataObject g1 = (DataObject) context.newObject("Generic1");
-        g1.writeProperty("name", "G1 Name");
-
-        DataObject g2 = (DataObject) context.newObject("Generic2");
-        g2.writeProperty("name", "G2 Name");
-        g2.setToOneTarget("toGeneric1", g1, true);
-
-        context.commitChanges();
-
-        List<?> r1 = (List<?>) g1.readProperty("generic2s");
-        assertTrue(r1.contains(g2));
-
-        DataObject g11 = (DataObject) context.newObject("Generic1");
-        g11.writeProperty("name", "G11 Name");
-        g2.setToOneTarget("toGeneric1", g11, true);
-
-        context.commitChanges();
-
-        List<?> r11 = (List<?>) g11.readProperty("generic2s");
-        assertTrue(r11.contains(g2));
-
-        List<?> r1_1 = (List<?>) g1.readProperty("generic2s");
-        assertFalse(r1_1.contains(g2));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinIT.java b/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinIT.java
new file mode 100644
index 0000000..12d676d
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinIT.java
@@ -0,0 +1,59 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.r1.Activity;
+import org.apache.cayenne.testdo.r1.ActivityResult;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Date;
+
+@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
+public class ManyToManyNoJoinIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("ACTIVITY");
+        dbHelper.deleteAll("RESULT");
+    }
+
+    public void testValidateForSave1() throws Exception {
+        ActivityResult result = context.newObject(ActivityResult.class);
+        result.setAppointDate(new Date(System.currentTimeMillis()));
+        result.setAppointNo(1);
+        result.setField("xx");
+
+        Activity activity = context.newObject(Activity.class);
+        activity.setAppointmentDate(result.getAppointDate());
+        activity.setAppointmentNo(result.getAppointNo());
+
+        activity.addToResults(result);
+        context.commitChanges();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinTest.java b/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinTest.java
deleted file mode 100644
index c379a8b..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/ManyToManyNoJoinTest.java
+++ /dev/null
@@ -1,59 +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;
-
-import java.sql.Date;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.r1.Activity;
-import org.apache.cayenne.testdo.r1.ActivityResult;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class ManyToManyNoJoinTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("ACTIVITY");
-        dbHelper.deleteAll("RESULT");
-    }
-
-    public void testValidateForSave1() throws Exception {
-        ActivityResult result = context.newObject(ActivityResult.class);
-        result.setAppointDate(new Date(System.currentTimeMillis()));
-        result.setAppointNo(1);
-        result.setField("xx");
-
-        Activity activity = context.newObject(Activity.class);
-        activity.setAppointmentDate(result.getAppointDate());
-        activity.setAppointmentNo(result.getAppointNo());
-
-        activity.addToResults(result);
-        context.commitChanges();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKIT.java b/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
new file mode 100644
index 0000000..ce4d44a
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
@@ -0,0 +1,69 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.relationship.MeaningfulFK;
+import org.apache.cayenne.testdo.relationship.RelationshipHelper;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.validation.ValidationResult;
+
+@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
+public class MeaningfulFKIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MEANINGFUL_FK");
+    }
+
+    public void testValidateForSave1() throws Exception {
+        MeaningfulFK testObject = context.newObject(MeaningfulFK.class);
+
+        ValidationResult validation = new ValidationResult();
+        testObject.validateForSave(validation);
+        assertTrue(
+                "Must fail validation due to missing required relationship",
+                validation.hasFailures());
+        assertEquals(
+                "Must fail validation due to missing required relationship",
+                1,
+                validation.getFailures().size());
+    }
+
+    public void testValidateForSave2() throws Exception {
+        MeaningfulFK testObject = context.newObject(MeaningfulFK.class);
+
+        RelationshipHelper related = testObject.getObjectContext().newObject(
+                RelationshipHelper.class);
+        testObject.setToRelationshipHelper(related);
+
+        ValidationResult validation = new ValidationResult();
+        testObject.validateForSave(validation);
+        assertFalse(validation.hasFailures());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKTest.java b/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKTest.java
deleted file mode 100644
index 43b0e42..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/MeaningfulFKTest.java
+++ /dev/null
@@ -1,69 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.relationship.MeaningfulFK;
-import org.apache.cayenne.testdo.relationship.RelationshipHelper;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.validation.ValidationResult;
-
-@UseServerRuntime(ServerCase.RELATIONSHIPS_PROJECT)
-public class MeaningfulFKTest extends ServerCase {
-
-    @Inject
-    private ObjectContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MEANINGFUL_FK");
-    }
-
-    public void testValidateForSave1() throws Exception {
-        MeaningfulFK testObject = context.newObject(MeaningfulFK.class);
-
-        ValidationResult validation = new ValidationResult();
-        testObject.validateForSave(validation);
-        assertTrue(
-                "Must fail validation due to missing required relationship",
-                validation.hasFailures());
-        assertEquals(
-                "Must fail validation due to missing required relationship",
-                1,
-                validation.getFailures().size());
-    }
-
-    public void testValidateForSave2() throws Exception {
-        MeaningfulFK testObject = context.newObject(MeaningfulFK.class);
-
-        RelationshipHelper related = testObject.getObjectContext().newObject(
-                RelationshipHelper.class);
-        testObject.setToRelationshipHelper(related);
-
-        ValidationResult validation = new ValidationResult();
-        testObject.validateForSave(validation);
-        assertFalse(validation.hasFailures());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/OneWayRelationshipsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/OneWayRelationshipsIT.java b/cayenne-server/src/test/java/org/apache/cayenne/OneWayRelationshipsIT.java
new file mode 100644
index 0000000..0bafab4
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/OneWayRelationshipsIT.java
@@ -0,0 +1,217 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SQLSelect;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.oneway.OnewayTable1;
+import org.apache.cayenne.testdo.oneway.OnewayTable2;
+import org.apache.cayenne.testdo.oneway.OnewayTable3;
+import org.apache.cayenne.testdo.oneway.OnewayTable4;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.SQLException;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.ONEWAY_PROJECT)
+public class OneWayRelationshipsIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper t1Helper;
+    private TableHelper t2Helper;
+    private TableHelper t3Helper;
+    private TableHelper t4Helper;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+
+        dbHelper.deleteAll("oneway_table2");
+        dbHelper.deleteAll("oneway_table1");
+        dbHelper.deleteAll("oneway_table4");
+        dbHelper.deleteAll("oneway_table3");
+
+        t1Helper = new TableHelper(dbHelper, "oneway_table1");
+        t1Helper.setColumns("ID");
+        t2Helper = new TableHelper(dbHelper, "oneway_table2");
+        t2Helper.setColumns("ID", "TABLE1_ID");
+
+        t3Helper = new TableHelper(dbHelper, "oneway_table3");
+        t3Helper.setColumns("ID");
+        t4Helper = new TableHelper(dbHelper, "oneway_table4");
+        t4Helper.setColumns("ID", "TABLE3_ID");
+    }
+
+    public void testToOne_TwoNew() throws SQLException {
+
+        OnewayTable1 t1 = context.newObject(OnewayTable1.class);
+        OnewayTable2 t2 = context.newObject(OnewayTable2.class);
+        t2.setToOneOneWayDb(t1);
+
+        context.commitChanges();
+
+        int t1Pk = t1Helper.getInt("ID");
+        assertEquals(Cayenne.intPKForObject(t1), t1Pk);
+        int t2FK = t2Helper.getInt("TABLE1_ID");
+        assertEquals(t1Pk, t2FK);
+    }
+
+    public void testToOne_Replace() throws SQLException {
+
+        t1Helper.insert(1).insert(2);
+        t2Helper.insert(1, 1);
+
+        OnewayTable1 t11 = Cayenne.objectForPK(context, OnewayTable1.class, 1);
+        OnewayTable1 t12 = Cayenne.objectForPK(context, OnewayTable1.class, 2);
+        OnewayTable2 t2 = Cayenne.objectForPK(context, OnewayTable2.class, 1);
+
+        assertSame(t11, t2.getToOneOneWayDb());
+
+        t2.setToOneOneWayDb(t12);
+        context.commitChanges();
+
+        assertSame(t12, t2.getToOneOneWayDb());
+
+        int t2FK = t2Helper.getInt("TABLE1_ID");
+        assertEquals(2, t2FK);
+    }
+
+    public void testToOne_ReplaceWithNull() throws SQLException {
+
+        t1Helper.insert(1);
+        t2Helper.insert(1, 1);
+
+        OnewayTable1 t11 = Cayenne.objectForPK(context, OnewayTable1.class, 1);
+        OnewayTable2 t2 = Cayenne.objectForPK(context, OnewayTable2.class, 1);
+
+        assertSame(t11, t2.getToOneOneWayDb());
+
+        t2.setToOneOneWayDb(null);
+        context.commitChanges();
+
+        assertNull(t2.getToOneOneWayDb());
+
+        Object t2FK = t2Helper.getObject("TABLE1_ID");
+        assertNull(t2FK);
+    }
+
+    public void testToMany_TwoNew() throws SQLException {
+
+        OnewayTable3 t3 = context.newObject(OnewayTable3.class);
+        OnewayTable4 t4 = context.newObject(OnewayTable4.class);
+        t3.addToToManyOneWayDb(t4);
+
+        context.commitChanges();
+
+        int t3Pk = t3Helper.getInt("ID");
+        assertEquals(Cayenne.intPKForObject(t3), t3Pk);
+        int t4FK = t4Helper.getInt("TABLE3_ID");
+        assertEquals(t3Pk, t4FK);
+    }
+
+    public void testToMany_AddNew() throws SQLException {
+
+        t3Helper.insert(1);
+        t4Helper.insert(1, 1);
+
+        OnewayTable3 t3 = Cayenne.objectForPK(context, OnewayTable3.class, 1);
+        assertEquals(1, t3.getToManyOneWayDb().size());
+
+        OnewayTable4 t41 = Cayenne.objectForPK(context, OnewayTable4.class, 1);
+        assertTrue(t3.getToManyOneWayDb().contains(t41));
+
+        OnewayTable4 t42 = context.newObject(OnewayTable4.class);
+        t3.addToToManyOneWayDb(t42);
+        context.commitChanges();
+
+        assertEquals(2, t3.getToManyOneWayDb().size());
+
+        SQLSelect<Integer> fksQuery = SQLSelect.scalarQuery(Integer.class, "oneway-rels",
+                "SELECT TABLE3_ID FROM oneway_table4");
+
+        List<Integer> fks = context.select(fksQuery);
+        assertEquals(2, fks.size());
+        for (Integer fk : fks) {
+            assertEquals(Integer.valueOf(1), fk);
+        }
+    }
+
+    public void testToMany_AddExisting() throws SQLException {
+
+        t3Helper.insert(1);
+        t4Helper.insert(1, 1).insert(2, null);
+
+        OnewayTable3 t3 = Cayenne.objectForPK(context, OnewayTable3.class, 1);
+        assertEquals(1, t3.getToManyOneWayDb().size());
+
+        OnewayTable4 t41 = Cayenne.objectForPK(context, OnewayTable4.class, 1);
+        assertTrue(t3.getToManyOneWayDb().contains(t41));
+
+        OnewayTable4 t42 = Cayenne.objectForPK(context, OnewayTable4.class, 2);
+
+        t3.addToToManyOneWayDb(t42);
+        context.commitChanges();
+
+        assertEquals(2, t3.getToManyOneWayDb().size());
+
+        SQLSelect<Integer> fksQuery = SQLSelect.scalarQuery(Integer.class, "oneway-rels",
+                "SELECT TABLE3_ID FROM oneway_table4");
+
+        List<Integer> fks = context.select(fksQuery);
+        assertEquals(2, fks.size());
+        for (Integer fk : fks) {
+            assertEquals(Integer.valueOf(1), fk);
+        }
+    }
+
+    public void testToMany_RemoveExisting() throws SQLException {
+
+        t3Helper.insert(1);
+        t4Helper.insert(1, 1).insert(2, 1);
+
+        OnewayTable3 t3 = Cayenne.objectForPK(context, OnewayTable3.class, 1);
+        assertEquals(2, t3.getToManyOneWayDb().size());
+
+        OnewayTable4 t41 = Cayenne.objectForPK(context, OnewayTable4.class, 1);
+        assertTrue(t3.getToManyOneWayDb().contains(t41));
+
+        OnewayTable4 t42 = Cayenne.objectForPK(context, OnewayTable4.class, 2);
+        assertTrue(t3.getToManyOneWayDb().contains(t42));
+
+        t3.removeFromToManyOneWayDb(t42);
+        context.commitChanges();
+
+        assertEquals(1, t3.getToManyOneWayDb().size());
+
+        SQLSelect<Integer> fksQuery = SQLSelect.scalarQuery(Integer.class, "oneway-rels",
+                "SELECT TABLE3_ID FROM oneway_table4");
+
+        List<Integer> fks = context.select(fksQuery);
+        assertEquals(2, fks.size());
+        assertTrue(fks.contains(1));
+        assertTrue(fks.contains(null));
+    }
+}


Mime
View raw message