You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/11/02 08:10:05 UTC
[17/48] Installing Maven Failsafe Plugin
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
deleted file mode 100644
index f622f11..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
+++ /dev/null
@@ -1,292 +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.access;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.apache.cayenne.DataObject;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.Ordering;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-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.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class SimpleIdIncrementalFaultListTest extends ServerCase {
-
- @Inject
- private DataContext context;
-
- @Inject
- private DBHelper dbHelper;
-
- private TableHelper tArtist;
-
- @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");
- }
-
- protected void createArtistsDataSet() throws Exception {
- tArtist.insert(33001, "artist1");
- tArtist.insert(33002, "artist2");
- tArtist.insert(33003, "artist3");
- tArtist.insert(33004, "artist4");
- tArtist.insert(33005, "artist5");
- tArtist.insert(33006, "artist6");
- tArtist.insert(33007, "artist7");
- tArtist.insert(33008, "artist8");
- tArtist.insert(33009, "artist9");
- tArtist.insert(33010, "artist10");
- tArtist.insert(33011, "artist11");
- tArtist.insert(33012, "artist12");
- tArtist.insert(33013, "artist13");
- tArtist.insert(33014, "artist14");
- tArtist.insert(33015, "artist15");
- tArtist.insert(33016, "artist16");
- tArtist.insert(33017, "artist17");
- tArtist.insert(33018, "artist18");
- tArtist.insert(33019, "artist19");
- tArtist.insert(33020, "artist20");
- tArtist.insert(33021, "artist21");
- tArtist.insert(33022, "artist22");
- tArtist.insert(33023, "artist23");
- tArtist.insert(33024, "artist24");
- tArtist.insert(33025, "artist25");
- }
-
- public void testRemoveDeleted() throws Exception {
- createArtistsDataSet();
-
- // DataContext context = createDataContext();
-
- SelectQuery query = new SelectQuery(Artist.class);
- query.setPageSize(10);
- SimpleIdIncrementalFaultList<Artist> list = new SimpleIdIncrementalFaultList<Artist>(
- context,
- query, 10000);
-
- assertEquals(25, list.size());
-
- Artist a1 = list.get(0);
- context.deleteObjects(a1);
- context.commitChanges();
-
- list.remove(0);
- assertEquals(24, list.size());
- }
-
- private SimpleIdIncrementalFaultList<?> prepareList(int pageSize) throws Exception {
- createArtistsDataSet();
-
- SelectQuery query = new SelectQuery(Artist.class);
-
- // make sure total number of objects is not divisable
- // by the page size, to test the last smaller page
- query.setPageSize(pageSize);
- query.addOrdering("db:ARTIST_ID", SortOrder.ASCENDING);
- return new SimpleIdIncrementalFaultList<Object>(context, query, 10000);
- }
-
- public void testSize() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- assertEquals(25, list.size());
- }
-
- public void testSmallList() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(49);
- assertEquals(25, list.size());
- }
-
- public void testOnePageList() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(25);
- assertEquals(25, list.size());
- }
-
- public void testIterator() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- Iterator<?> it = list.iterator();
- int counter = 0;
- while (it.hasNext()) {
- Object obj = it.next();
- assertNotNull(obj);
- assertTrue(obj instanceof DataObject);
-
- // iterator must be resolved page by page
- int expectedResolved = list.pageIndex(counter)
- * list.getPageSize()
- + list.getPageSize();
- if (expectedResolved > list.size()) {
- expectedResolved = list.size();
- }
-
- assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
-
- counter++;
- }
- }
-
- public void testNewObject() throws Exception {
-
- createArtistsDataSet();
-
- Artist newArtist = context.newObject(Artist.class);
- newArtist.setArtistName("x");
- context.commitChanges();
-
- SelectQuery<Artist> q = new SelectQuery<Artist>(Artist.class);
- q.setPageSize(6);
- q.addOrdering(Artist.ARTIST_NAME.asc());
-
- SimpleIdIncrementalFaultList<?> list = new SimpleIdIncrementalFaultList<Object>(
- context,
- q, 10000);
-
- assertSame(newArtist, list.get(25));
- }
-
- public void testListIterator() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- ListIterator<?> it = list.listIterator();
- int counter = 0;
- while (it.hasNext()) {
- Object obj = it.next();
- assertNotNull(obj);
- assertTrue(obj instanceof DataObject);
-
- // iterator must be resolved page by page
- int expectedResolved = list.pageIndex(counter)
- * list.getPageSize()
- + list.getPageSize();
- if (expectedResolved > list.size()) {
- expectedResolved = list.size();
- }
-
- assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
-
- counter++;
- }
- }
-
- public void testSort() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
-
- new Ordering(Artist.ARTIST_NAME_PROPERTY, SortOrder.DESCENDING).orderList(list);
-
- Iterator<?> it = list.iterator();
- Artist previousArtist = null;
- while (it.hasNext()) {
- Artist artist = (Artist) it.next();
- if (previousArtist != null) {
- assertTrue(previousArtist.getArtistName().compareTo(
- artist.getArtistName()) > 0);
- }
- }
- }
-
- public void testUnfetchedObjects() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- assertEquals(25, list.getUnfetchedObjects());
- list.get(7);
- assertEquals(25 - 6, list.getUnfetchedObjects());
- list.resolveAll();
- assertEquals(0, list.getUnfetchedObjects());
- }
-
- public void testPageIndex() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- assertEquals(0, list.pageIndex(0));
- assertEquals(0, list.pageIndex(1));
- assertEquals(1, list.pageIndex(6));
-
- try {
- assertEquals(13, list.pageIndex(82));
- fail("Element index beyound array size must throw an IndexOutOfBoundsException.");
- }
- catch (IndexOutOfBoundsException ex) {
- // exception expercted
- }
- }
-
- public void testPagesRead1() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- assertTrue(list.elements.get(0) instanceof Long);
- assertTrue(list.elements.get(8) instanceof Long);
-
- list.resolveInterval(5, 10);
- assertTrue(list.elements.get(7) instanceof Artist);
-
- list.resolveAll();
- assertTrue((list.elements.get(list.size() - 1)) instanceof Artist);
- }
-
- public void testGet1() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- assertTrue(list.elements.get(0) instanceof Long);
- assertTrue(list.elements.get(8) instanceof Long);
-
- Object a = list.get(8);
-
- assertNotNull(a);
- assertTrue(a instanceof Artist);
- assertTrue(list.elements.get(8) instanceof Artist);
- }
-
- public void testIndexOf() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- Expression qual = ExpressionFactory.matchExp("artistName", "artist20");
- SelectQuery query = new SelectQuery(Artist.class, qual);
- List<?> artists = list.dataContext.performQuery(query);
-
- assertEquals(1, artists.size());
-
- Artist row = (Artist) artists.get(0);
- assertEquals(19, list.indexOf(row));
- assertEquals(-1, list.indexOf(list.dataContext.newObject("Artist")));
- }
-
- public void testLastIndexOf() throws Exception {
- SimpleIdIncrementalFaultList<?> list = prepareList(6);
- Expression qual = ExpressionFactory.matchExp("artistName", "artist20");
- SelectQuery query = new SelectQuery(Artist.class, qual);
- List<?> artists = list.dataContext.performQuery(query);
-
- assertEquals(1, artists.size());
-
- Artist row = (Artist) artists.get(0);
- assertEquals(19, list.lastIndexOf(row));
- assertEquals(-1, list.lastIndexOf(list.dataContext.newObject("Artist")));
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1IT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1IT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1IT.java
new file mode 100644
index 0000000..32220f0
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1IT.java
@@ -0,0 +1,102 @@
+/*****************************************************************
+ * 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.access;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.inheritance_flat.Group;
+import org.apache.cayenne.testdo.inheritance_flat.Role;
+import org.apache.cayenne.testdo.inheritance_flat.User;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+/**
+ * Special test cases per CAY-1378, CAY-1379.
+ */
+@UseServerRuntime(ServerCase.INHERTITANCE_SINGLE_TABLE1_PROJECT)
+public class SingleTableInheritance1IT extends ServerCase {
+
+ @Inject
+ private ObjectContext context;
+
+ @Inject
+ private DBHelper dbHelper;
+
+ @Override
+ protected void setUpAfterInjection() throws Exception {
+
+ dbHelper.deleteAll("GROUP_MEMBERS");
+ dbHelper.deleteAll("USER_PROPERTIES");
+ dbHelper.deleteAll("GROUP_PROPERTIES");
+ dbHelper.deleteAll("ROLES");
+ }
+
+ public void testGroupActions() throws Exception {
+
+ User user = context.newObject(User.class);
+ user.setName("test_user");
+
+ Group group1 = context.newObject(Group.class);
+ group1.setName("test_group1");
+
+ Group group2 = context.newObject(Group.class);
+ group2.setName("test_group2");
+
+ group1.addToGroupMembers(user);
+ group2.addToGroupMembers(group1);
+
+ group2.getObjectContext().commitChanges();
+
+ // Per CAY-1379 removing user and then refetching resulted in a FFE downstream
+ group1.removeFromGroupMembers(user);
+ Expression exp = ExpressionFactory.matchExp(Role.ROLE_GROUPS_PROPERTY, group2);
+ SelectQuery query = new SelectQuery(Group.class, exp);
+ context.performQuery(query);
+ context.commitChanges();
+
+ context.deleteObjects(group1);
+ context.deleteObjects(group2);
+ context.deleteObjects(user);
+ context.commitChanges();
+ }
+
+ public void testFlattenedNullifyNullifyDeleteRules() throws Exception {
+
+ User user = context.newObject(User.class);
+ user.setName("test_user");
+ Group group = context.newObject(Group.class);
+ group.setName("test_group");
+ group.addToGroupMembers(user);
+ context.commitChanges();
+
+ context.deleteObjects(user);
+ assertTrue(group.getGroupMembers().isEmpty());
+
+ context.commitChanges();
+
+ // here Cayenne would throw per CAY-1378 on an attempt to delete a previously
+ // related transient object
+ context.deleteObjects(group);
+ context.commitChanges();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1Test.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1Test.java b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1Test.java
deleted file mode 100644
index 6b71456..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritance1Test.java
+++ /dev/null
@@ -1,102 +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.access;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.inheritance_flat.Group;
-import org.apache.cayenne.testdo.inheritance_flat.Role;
-import org.apache.cayenne.testdo.inheritance_flat.User;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * Special test cases per CAY-1378, CAY-1379.
- */
-@UseServerRuntime(ServerCase.INHERTITANCE_SINGLE_TABLE1_PROJECT)
-public class SingleTableInheritance1Test extends ServerCase {
-
- @Inject
- private ObjectContext context;
-
- @Inject
- private DBHelper dbHelper;
-
- @Override
- protected void setUpAfterInjection() throws Exception {
-
- dbHelper.deleteAll("GROUP_MEMBERS");
- dbHelper.deleteAll("USER_PROPERTIES");
- dbHelper.deleteAll("GROUP_PROPERTIES");
- dbHelper.deleteAll("ROLES");
- }
-
- public void testGroupActions() throws Exception {
-
- User user = context.newObject(User.class);
- user.setName("test_user");
-
- Group group1 = context.newObject(Group.class);
- group1.setName("test_group1");
-
- Group group2 = context.newObject(Group.class);
- group2.setName("test_group2");
-
- group1.addToGroupMembers(user);
- group2.addToGroupMembers(group1);
-
- group2.getObjectContext().commitChanges();
-
- // Per CAY-1379 removing user and then refetching resulted in a FFE downstream
- group1.removeFromGroupMembers(user);
- Expression exp = ExpressionFactory.matchExp(Role.ROLE_GROUPS_PROPERTY, group2);
- SelectQuery query = new SelectQuery(Group.class, exp);
- context.performQuery(query);
- context.commitChanges();
-
- context.deleteObjects(group1);
- context.deleteObjects(group2);
- context.deleteObjects(user);
- context.commitChanges();
- }
-
- public void testFlattenedNullifyNullifyDeleteRules() throws Exception {
-
- User user = context.newObject(User.class);
- user.setName("test_user");
- Group group = context.newObject(Group.class);
- group.setName("test_group");
- group.addToGroupMembers(user);
- context.commitChanges();
-
- context.deleteObjects(user);
- assertTrue(group.getGroupMembers().isEmpty());
-
- context.commitChanges();
-
- // here Cayenne would throw per CAY-1378 on an attempt to delete a previously
- // related transient object
- context.deleteObjects(group);
- context.commitChanges();
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceIT.java
new file mode 100644
index 0000000..ea76fa7
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceIT.java
@@ -0,0 +1,533 @@
+/*****************************************************************
+ * 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.access;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.PrefetchTreeNode;
+import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.SortOrder;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.inherit.AbstractPerson;
+import org.apache.cayenne.testdo.inherit.Address;
+import org.apache.cayenne.testdo.inherit.BaseEntity;
+import org.apache.cayenne.testdo.inherit.ClientCompany;
+import org.apache.cayenne.testdo.inherit.CustomerRepresentative;
+import org.apache.cayenne.testdo.inherit.Department;
+import org.apache.cayenne.testdo.inherit.Employee;
+import org.apache.cayenne.testdo.inherit.Manager;
+import org.apache.cayenne.testdo.inherit.PersonNotes;
+import org.apache.cayenne.testdo.inherit.RelatedEntity;
+import org.apache.cayenne.testdo.inherit.SubEntity;
+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.Types;
+import java.util.Arrays;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.PEOPLE_PROJECT)
+public class SingleTableInheritanceIT extends ServerCase {
+
+ @Inject
+ private DBHelper dbHelper;
+
+ @Inject
+ private DataContext context;
+
+ @Inject
+ private DataContext context2;
+
+ @Inject
+ private DataChannelInterceptor queryBlocker;
+
+ private TableHelper tPerson;
+ private TableHelper tAddress;
+ private TableHelper tClientCompany;
+ private TableHelper tDepartment;
+
+ @Override
+ protected void setUpAfterInjection() throws Exception {
+ tPerson = new TableHelper(dbHelper, "PERSON");
+ tPerson.setColumns(
+ "PERSON_ID",
+ "NAME",
+ "PERSON_TYPE",
+ "SALARY",
+ "CLIENT_COMPANY_ID",
+ "DEPARTMENT_ID").setColumnTypes(
+ Types.INTEGER,
+ Types.VARCHAR,
+ Types.CHAR,
+ Types.FLOAT,
+ Types.INTEGER,
+ Types.INTEGER);
+
+ tAddress = new TableHelper(dbHelper, "ADDRESS");
+ tAddress.setColumns("ADDRESS_ID", "CITY", "PERSON_ID");
+
+ tClientCompany = new TableHelper(dbHelper, "CLIENT_COMPANY");
+ tClientCompany.setColumns("CLIENT_COMPANY_ID", "NAME");
+
+ tDepartment = new TableHelper(dbHelper, "DEPARTMENT");
+ tDepartment.setColumns("DEPARTMENT_ID", "NAME");
+
+ // manually break circular deps
+ tPerson.update().set("DEPARTMENT_ID", null, Types.INTEGER).execute();
+
+ dbHelper.deleteAll("ADDRESS");
+ dbHelper.deleteAll("DEPARTMENT");
+ dbHelper.deleteAll("PERSON_NOTES");
+ dbHelper.deleteAll("PERSON");
+ dbHelper.deleteAll("CLIENT_COMPANY");
+ }
+
+ private void create2PersonDataSet() throws Exception {
+ tPerson.insert(1, "E1", "EE", null, null, null);
+ tPerson.insert(2, "E2", "EM", null, null, null);
+ }
+
+ private void create5PersonDataSet() throws Exception {
+ tPerson.insert(1, "E1", "EE", null, null, null);
+ tPerson.insert(2, "E2", "EM", null, null, null);
+ tPerson.insert(3, "E3", "EE", null, null, null);
+ tPerson.insert(4, "E4", "EM", null, null, null);
+ tPerson.insert(5, "E5", "EE", null, null, null);
+ }
+
+ private void createSelectDataSet() throws Exception {
+ tPerson.insert(1, "e1", "EE", 20000, null, null);
+ tPerson.insert(2, "e2", "EE", 25000, null, null);
+ tPerson.insert(3, "e3", "EE", 28000, null, null);
+ tPerson.insert(4, "m1", "EM", 30000, null, null);
+ tPerson.insert(5, "m2", "EM", 40000, null, null);
+
+ tClientCompany.insert(1, "Citibank");
+ tPerson.insert(6, "c1", "C", null, 1, null);
+ }
+
+ private void createEmployeeAddressDataSet() throws Exception {
+ tPerson.insert(1, "e1", "EE", 20000, null, null);
+ tAddress.insert(1, "New York", 1);
+ }
+
+ private void createManagerAddressDataSet() throws Exception {
+ tPerson.insert(4, "m1", "EM", 30000, null, null);
+ tAddress.insert(1, "New York", 4);
+ }
+
+ private void createRepCompanyDataSet() throws Exception {
+ tClientCompany.insert(1, "Citibank");
+ tPerson.insert(6, "c1", "C", null, 1, null);
+ }
+
+ private void createDepartmentEmployeesDataSet() throws Exception {
+ tDepartment.insert(1, "Accounting");
+
+ tPerson.insert(7, "John", "EE", 25000, null, 1);
+ tPerson.insert(8, "Susan", "EE", 50000, null, 1);
+ tPerson.insert(9, "Kelly", "EM", 100000, null, 1);
+ }
+
+ public void testMatchingOnSuperAttributes() throws Exception {
+ create2PersonDataSet();
+
+ // fetch on leaf, but match on a super attribute
+ SelectQuery select = new SelectQuery(Manager.class);
+ select.andQualifier(ExpressionFactory
+ .matchExp(AbstractPerson.NAME_PROPERTY, "E2"));
+
+ List<Manager> results = context.performQuery(select);
+ assertEquals(1, results.size());
+ assertEquals("E2", results.get(0).getName());
+ }
+
+ public void testMatchingOnSuperAttributesWithPrefetch() throws Exception {
+ create2PersonDataSet();
+
+ // fetch on leaf, but match on a super attribute
+ SelectQuery select = new SelectQuery(Employee.class);
+ select.addPrefetch(Employee.TO_DEPARTMENT_PROPERTY);
+ select.andQualifier(ExpressionFactory
+ .matchExp(AbstractPerson.NAME_PROPERTY, "E2"));
+
+ List<Manager> results = context.performQuery(select);
+ assertEquals(1, results.size());
+ assertEquals("E2", results.get(0).getName());
+ }
+
+ public void testPaginatedQueries() throws Exception {
+
+ create5PersonDataSet();
+
+ SelectQuery select = new SelectQuery(AbstractPerson.class);
+ select.addOrdering(
+ "db:" + AbstractPerson.PERSON_ID_PK_COLUMN,
+ SortOrder.ASCENDING);
+ select.setPageSize(3);
+
+ List<AbstractPerson> results = context.performQuery(select);
+ assertEquals(5, results.size());
+
+ assertTrue(results.get(0) instanceof Employee);
+
+ // this is where things would blow up per CAY-1142
+ assertTrue(results.get(1) instanceof Manager);
+
+ assertTrue(results.get(3) instanceof Manager);
+ assertTrue(results.get(4) instanceof Employee);
+ }
+
+ public void testRelationshipToAbstractSuper() {
+ context
+ .performGenericQuery(new SQLTemplate(
+ AbstractPerson.class,
+ "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (1, 'AA', 'EE')"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (1, 'AA', 1)"));
+
+ PersonNotes note = Cayenne.objectForPK(context, PersonNotes.class, 1);
+ assertNotNull(note);
+ assertNotNull(note.getPerson());
+ assertTrue(note.getPerson() instanceof Employee);
+ }
+
+ public void testRelationshipAbstractFromSuperPrefetchingJoint() {
+ context
+ .performGenericQuery(new SQLTemplate(
+ AbstractPerson.class,
+ "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (4, 'BB', 3)"));
+
+ SelectQuery query = new SelectQuery(AbstractPerson.class);
+ query.addPrefetch(AbstractPerson.NOTES_PROPERTY).setSemantics(
+ PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+ final AbstractPerson person = (AbstractPerson) Cayenne.objectForQuery(
+ context,
+ query);
+
+ assertTrue(person instanceof Employee);
+
+ queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+ public void execute() {
+ assertEquals(2, person.getNotes().size());
+
+ String[] names = new String[2];
+ names[0] = person.getNotes().get(0).getNotes();
+ names[1] = person.getNotes().get(1).getNotes();
+ List<String> nameSet = Arrays.asList(names);
+
+ assertTrue(nameSet.contains("AA"));
+ assertTrue(nameSet.contains("BB"));
+ }
+ });
+ }
+
+ public void testRelationshipAbstractFromSuperPrefetchingDisjoint() {
+ context
+ .performGenericQuery(new SQLTemplate(
+ AbstractPerson.class,
+ "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (4, 'BB', 3)"));
+
+ SelectQuery query = new SelectQuery(AbstractPerson.class);
+ query.addPrefetch(AbstractPerson.NOTES_PROPERTY);
+
+ final AbstractPerson person = (AbstractPerson) Cayenne.objectForQuery(
+ context,
+ query);
+ assertTrue(person instanceof Employee);
+
+ queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+ public void execute() {
+ assertEquals(2, person.getNotes().size());
+
+ String[] names = new String[2];
+ names[0] = person.getNotes().get(0).getNotes();
+ names[1] = person.getNotes().get(1).getNotes();
+ List<String> nameSet = Arrays.asList(names);
+
+ assertTrue(nameSet.contains("AA"));
+ assertTrue(nameSet.contains("BB"));
+ }
+ });
+ }
+
+ public void testRelationshipAbstractToSuperPrefetchingDisjoint() {
+ context
+ .performGenericQuery(new SQLTemplate(
+ AbstractPerson.class,
+ "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (2, 'AA', 'EE')"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (2, 'AA', 2)"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'BB', 2)"));
+
+ SelectQuery query = new SelectQuery(PersonNotes.class);
+ query.addPrefetch(PersonNotes.PERSON_PROPERTY);
+ query.addOrdering(PersonNotes.NOTES_PROPERTY, SortOrder.ASCENDING);
+
+ List<PersonNotes> notes = context.performQuery(query);
+ assertEquals(2, notes.size());
+ final PersonNotes note = notes.get(0);
+
+ queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+ public void execute() {
+ assertEquals("AA", note.getPerson().getName());
+ }
+ });
+ }
+
+ public void testRelationshipAbstractToSuperPrefetchingJoint() {
+ context
+ .performGenericQuery(new SQLTemplate(
+ AbstractPerson.class,
+ "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
+
+ context.performGenericQuery(new SQLTemplate(
+ PersonNotes.class,
+ "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
+
+ SelectQuery query = new SelectQuery(PersonNotes.class);
+ query.addPrefetch(PersonNotes.PERSON_PROPERTY).setSemantics(
+ PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+ final PersonNotes note = (PersonNotes) Cayenne.objectForQuery(context, query);
+
+ queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
+
+ public void execute() {
+ assertEquals("AA", note.getPerson().getName());
+ }
+ });
+
+ }
+
+ public void testSave() throws Exception {
+ ClientCompany company = context.newObject(ClientCompany.class);
+ company.setName("Boeing");
+
+ CustomerRepresentative rep = context.newObject(CustomerRepresentative.class);
+ rep.setName("Joe Schmoe");
+ rep.setToClientCompany(company);
+ rep.setPersonType("C");
+
+ Employee employee = context.newObject(Employee.class);
+ employee.setName("Our Joe Schmoe");
+ employee.setPersonType("E");
+
+ context.commitChanges();
+ context.invalidateObjects(company, rep, employee);
+
+ SelectQuery query = new SelectQuery(CustomerRepresentative.class);
+ List<?> reps = context2.performQuery(query);
+
+ assertEquals(1, reps.size());
+ assertEquals(1, countObjectOfClass(reps, CustomerRepresentative.class));
+ }
+
+ /**
+ * Tests that to-one relationship produces correct subclass.
+ */
+ public void testEmployeeAddress() throws Exception {
+ createEmployeeAddressDataSet();
+
+ List<?> addresses = context.performQuery(new SelectQuery(Address.class));
+
+ assertEquals(1, addresses.size());
+ Address address = (Address) addresses.get(0);
+ assertSame(Employee.class, address.getToEmployee().getClass());
+ }
+
+ /**
+ * Tests that to-one relationship produces correct subclass.
+ */
+ public void testManagerAddress() throws Exception {
+ createManagerAddressDataSet();
+
+ List<?> addresses = context.performQuery(new SelectQuery(Address.class));
+
+ assertEquals(1, addresses.size());
+ Address address = (Address) addresses.get(0);
+ Employee e = address.getToEmployee();
+
+ assertSame(Manager.class, e.getClass());
+ }
+
+ public void testCAY592() throws Exception {
+ createManagerAddressDataSet();
+
+ List<?> addresses = context.performQuery(new SelectQuery(Address.class));
+
+ assertEquals(1, addresses.size());
+ Address address = (Address) addresses.get(0);
+ Employee e = address.getToEmployee();
+
+ // CAY-592 - make sure modification of the address in a parallel context
+ // doesn't mess up the Manager
+
+ e = (Employee) Cayenne.objectForPK(context2, e.getObjectId());
+ address = e.getAddresses().get(0);
+
+ assertSame(e, address.getToEmployee());
+ address.setCity("XYZ");
+ assertSame(e, address.getToEmployee());
+ }
+
+ /**
+ * Tests that to-one relationship produces correct subclass.
+ */
+ public void testRepCompany() throws Exception {
+ createRepCompanyDataSet();
+
+ List<?> companies = context.performQuery(new SelectQuery(ClientCompany.class));
+
+ assertEquals(1, companies.size());
+ ClientCompany company = (ClientCompany) companies.get(0);
+ List<?> reps = company.getRepresentatives();
+ assertEquals(1, reps.size());
+ assertSame(CustomerRepresentative.class, reps.get(0).getClass());
+ }
+
+ /**
+ * Tests that to-many relationship produces correct subclasses.
+ */
+ public void testDepartmentEmployees() throws Exception {
+ createDepartmentEmployeesDataSet();
+
+ List<?> departments = context.performQuery(new SelectQuery(Department.class));
+
+ assertEquals(1, departments.size());
+ Department dept = (Department) departments.get(0);
+ List<?> employees = dept.getEmployees();
+ assertEquals(3, employees.size());
+ assertEquals(3, countObjectOfClass(employees, Employee.class));
+ assertEquals(1, countObjectOfClass(employees, Manager.class));
+ }
+
+ public void testSelectInheritanceResolving() throws Exception {
+ createSelectDataSet();
+
+ SelectQuery query = new SelectQuery(AbstractPerson.class);
+ List<?> abstractPpl = context.performQuery(query);
+ assertEquals(6, abstractPpl.size());
+
+ assertEquals(1, countObjectOfClass(abstractPpl, CustomerRepresentative.class));
+ assertEquals(5, countObjectOfClass(abstractPpl, Employee.class));
+ assertEquals(2, countObjectOfClass(abstractPpl, Manager.class));
+ }
+
+ /**
+ * Test for CAY-1008: Reverse relationships may not be correctly set if inheritance is
+ * used.
+ */
+ public void testCAY1008() {
+ RelatedEntity related = context.newObject(RelatedEntity.class);
+
+ BaseEntity base = context.newObject(BaseEntity.class);
+ base.setToRelatedEntity(related);
+
+ assertEquals(1, related.getBaseEntities().size());
+ assertEquals(0, related.getSubEntities().size());
+
+ SubEntity sub = context.newObject(SubEntity.class);
+ sub.setToRelatedEntity(related);
+
+ assertEquals(2, related.getBaseEntities().size());
+
+ // TODO: andrus 2008/03/28 - this fails...
+ // assertEquals(1, related.getSubEntities().size());
+ }
+
+ /**
+ * Test for CAY-1009: Bogus runtime relationships can mess up commit.
+ */
+ public void testCAY1009() {
+
+ // We should have only one relationship. DirectToSubEntity -> SubEntity.
+
+ // this fails as a result of 'EntityResolver().applyObjectLayerDefaults()'
+ // creating incorrect relationships
+ // assertEquals(1, context
+ // .getEntityResolver()
+ // .getObjEntity("DirectToSubEntity")
+ // .getRelationships()
+ // .size());
+
+ // We should still just have the one mapped relationship, but we in fact now have
+ // two:
+ // DirectToSubEntity -> BaseEntity and DirectToSubEntity -> SubEntity.
+
+ // TODO: andrus 2008/03/28 - this fails...
+ // assertEquals(1, context.getEntityResolver().getObjEntity("DirectToSubEntity")
+ // .getRelationships().size());
+ //
+ // DirectToSubEntity direct = context.newObject(DirectToSubEntity.class);
+ //
+ // SubEntity sub = context.newObject(SubEntity.class);
+ // sub.setToDirectToSubEntity(direct);
+ //
+ // assertEquals(1, direct.getSubEntities().size());
+ //
+ // context.deleteObject(sub);
+ // assertEquals(0, direct.getSubEntities().size());
+ }
+
+ /**
+ * Returns a number of objects of a particular class and subclasses in the list.
+ */
+ private int countObjectOfClass(List<?> objects, Class<?> aClass) {
+ int i = 0;
+
+ for (Object next : objects) {
+ if (aClass.isAssignableFrom(next.getClass())) {
+ i++;
+ }
+ }
+ return i;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceTest.java
deleted file mode 100644
index 3bc5f68..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/SingleTableInheritanceTest.java
+++ /dev/null
@@ -1,533 +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.access;
-
-import java.sql.Types;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.SQLTemplate;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.inherit.AbstractPerson;
-import org.apache.cayenne.testdo.inherit.Address;
-import org.apache.cayenne.testdo.inherit.BaseEntity;
-import org.apache.cayenne.testdo.inherit.ClientCompany;
-import org.apache.cayenne.testdo.inherit.CustomerRepresentative;
-import org.apache.cayenne.testdo.inherit.Department;
-import org.apache.cayenne.testdo.inherit.Employee;
-import org.apache.cayenne.testdo.inherit.Manager;
-import org.apache.cayenne.testdo.inherit.PersonNotes;
-import org.apache.cayenne.testdo.inherit.RelatedEntity;
-import org.apache.cayenne.testdo.inherit.SubEntity;
-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.PEOPLE_PROJECT)
-public class SingleTableInheritanceTest extends ServerCase {
-
- @Inject
- private DBHelper dbHelper;
-
- @Inject
- private DataContext context;
-
- @Inject
- private DataContext context2;
-
- @Inject
- private DataChannelInterceptor queryBlocker;
-
- private TableHelper tPerson;
- private TableHelper tAddress;
- private TableHelper tClientCompany;
- private TableHelper tDepartment;
-
- @Override
- protected void setUpAfterInjection() throws Exception {
- tPerson = new TableHelper(dbHelper, "PERSON");
- tPerson.setColumns(
- "PERSON_ID",
- "NAME",
- "PERSON_TYPE",
- "SALARY",
- "CLIENT_COMPANY_ID",
- "DEPARTMENT_ID").setColumnTypes(
- Types.INTEGER,
- Types.VARCHAR,
- Types.CHAR,
- Types.FLOAT,
- Types.INTEGER,
- Types.INTEGER);
-
- tAddress = new TableHelper(dbHelper, "ADDRESS");
- tAddress.setColumns("ADDRESS_ID", "CITY", "PERSON_ID");
-
- tClientCompany = new TableHelper(dbHelper, "CLIENT_COMPANY");
- tClientCompany.setColumns("CLIENT_COMPANY_ID", "NAME");
-
- tDepartment = new TableHelper(dbHelper, "DEPARTMENT");
- tDepartment.setColumns("DEPARTMENT_ID", "NAME");
-
- // manually break circular deps
- tPerson.update().set("DEPARTMENT_ID", null, Types.INTEGER).execute();
-
- dbHelper.deleteAll("ADDRESS");
- dbHelper.deleteAll("DEPARTMENT");
- dbHelper.deleteAll("PERSON_NOTES");
- dbHelper.deleteAll("PERSON");
- dbHelper.deleteAll("CLIENT_COMPANY");
- }
-
- private void create2PersonDataSet() throws Exception {
- tPerson.insert(1, "E1", "EE", null, null, null);
- tPerson.insert(2, "E2", "EM", null, null, null);
- }
-
- private void create5PersonDataSet() throws Exception {
- tPerson.insert(1, "E1", "EE", null, null, null);
- tPerson.insert(2, "E2", "EM", null, null, null);
- tPerson.insert(3, "E3", "EE", null, null, null);
- tPerson.insert(4, "E4", "EM", null, null, null);
- tPerson.insert(5, "E5", "EE", null, null, null);
- }
-
- private void createSelectDataSet() throws Exception {
- tPerson.insert(1, "e1", "EE", 20000, null, null);
- tPerson.insert(2, "e2", "EE", 25000, null, null);
- tPerson.insert(3, "e3", "EE", 28000, null, null);
- tPerson.insert(4, "m1", "EM", 30000, null, null);
- tPerson.insert(5, "m2", "EM", 40000, null, null);
-
- tClientCompany.insert(1, "Citibank");
- tPerson.insert(6, "c1", "C", null, 1, null);
- }
-
- private void createEmployeeAddressDataSet() throws Exception {
- tPerson.insert(1, "e1", "EE", 20000, null, null);
- tAddress.insert(1, "New York", 1);
- }
-
- private void createManagerAddressDataSet() throws Exception {
- tPerson.insert(4, "m1", "EM", 30000, null, null);
- tAddress.insert(1, "New York", 4);
- }
-
- private void createRepCompanyDataSet() throws Exception {
- tClientCompany.insert(1, "Citibank");
- tPerson.insert(6, "c1", "C", null, 1, null);
- }
-
- private void createDepartmentEmployeesDataSet() throws Exception {
- tDepartment.insert(1, "Accounting");
-
- tPerson.insert(7, "John", "EE", 25000, null, 1);
- tPerson.insert(8, "Susan", "EE", 50000, null, 1);
- tPerson.insert(9, "Kelly", "EM", 100000, null, 1);
- }
-
- public void testMatchingOnSuperAttributes() throws Exception {
- create2PersonDataSet();
-
- // fetch on leaf, but match on a super attribute
- SelectQuery select = new SelectQuery(Manager.class);
- select.andQualifier(ExpressionFactory
- .matchExp(AbstractPerson.NAME_PROPERTY, "E2"));
-
- List<Manager> results = context.performQuery(select);
- assertEquals(1, results.size());
- assertEquals("E2", results.get(0).getName());
- }
-
- public void testMatchingOnSuperAttributesWithPrefetch() throws Exception {
- create2PersonDataSet();
-
- // fetch on leaf, but match on a super attribute
- SelectQuery select = new SelectQuery(Employee.class);
- select.addPrefetch(Employee.TO_DEPARTMENT_PROPERTY);
- select.andQualifier(ExpressionFactory
- .matchExp(AbstractPerson.NAME_PROPERTY, "E2"));
-
- List<Manager> results = context.performQuery(select);
- assertEquals(1, results.size());
- assertEquals("E2", results.get(0).getName());
- }
-
- public void testPaginatedQueries() throws Exception {
-
- create5PersonDataSet();
-
- SelectQuery select = new SelectQuery(AbstractPerson.class);
- select.addOrdering(
- "db:" + AbstractPerson.PERSON_ID_PK_COLUMN,
- SortOrder.ASCENDING);
- select.setPageSize(3);
-
- List<AbstractPerson> results = context.performQuery(select);
- assertEquals(5, results.size());
-
- assertTrue(results.get(0) instanceof Employee);
-
- // this is where things would blow up per CAY-1142
- assertTrue(results.get(1) instanceof Manager);
-
- assertTrue(results.get(3) instanceof Manager);
- assertTrue(results.get(4) instanceof Employee);
- }
-
- public void testRelationshipToAbstractSuper() {
- context
- .performGenericQuery(new SQLTemplate(
- AbstractPerson.class,
- "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (1, 'AA', 'EE')"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (1, 'AA', 1)"));
-
- PersonNotes note = Cayenne.objectForPK(context, PersonNotes.class, 1);
- assertNotNull(note);
- assertNotNull(note.getPerson());
- assertTrue(note.getPerson() instanceof Employee);
- }
-
- public void testRelationshipAbstractFromSuperPrefetchingJoint() {
- context
- .performGenericQuery(new SQLTemplate(
- AbstractPerson.class,
- "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (4, 'BB', 3)"));
-
- SelectQuery query = new SelectQuery(AbstractPerson.class);
- query.addPrefetch(AbstractPerson.NOTES_PROPERTY).setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
- final AbstractPerson person = (AbstractPerson) Cayenne.objectForQuery(
- context,
- query);
-
- assertTrue(person instanceof Employee);
-
- queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(2, person.getNotes().size());
-
- String[] names = new String[2];
- names[0] = person.getNotes().get(0).getNotes();
- names[1] = person.getNotes().get(1).getNotes();
- List<String> nameSet = Arrays.asList(names);
-
- assertTrue(nameSet.contains("AA"));
- assertTrue(nameSet.contains("BB"));
- }
- });
- }
-
- public void testRelationshipAbstractFromSuperPrefetchingDisjoint() {
- context
- .performGenericQuery(new SQLTemplate(
- AbstractPerson.class,
- "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (4, 'BB', 3)"));
-
- SelectQuery query = new SelectQuery(AbstractPerson.class);
- query.addPrefetch(AbstractPerson.NOTES_PROPERTY);
-
- final AbstractPerson person = (AbstractPerson) Cayenne.objectForQuery(
- context,
- query);
- assertTrue(person instanceof Employee);
-
- queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(2, person.getNotes().size());
-
- String[] names = new String[2];
- names[0] = person.getNotes().get(0).getNotes();
- names[1] = person.getNotes().get(1).getNotes();
- List<String> nameSet = Arrays.asList(names);
-
- assertTrue(nameSet.contains("AA"));
- assertTrue(nameSet.contains("BB"));
- }
- });
- }
-
- public void testRelationshipAbstractToSuperPrefetchingDisjoint() {
- context
- .performGenericQuery(new SQLTemplate(
- AbstractPerson.class,
- "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (2, 'AA', 'EE')"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (2, 'AA', 2)"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'BB', 2)"));
-
- SelectQuery query = new SelectQuery(PersonNotes.class);
- query.addPrefetch(PersonNotes.PERSON_PROPERTY);
- query.addOrdering(PersonNotes.NOTES_PROPERTY, SortOrder.ASCENDING);
-
- List<PersonNotes> notes = context.performQuery(query);
- assertEquals(2, notes.size());
- final PersonNotes note = notes.get(0);
-
- queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals("AA", note.getPerson().getName());
- }
- });
- }
-
- public void testRelationshipAbstractToSuperPrefetchingJoint() {
- context
- .performGenericQuery(new SQLTemplate(
- AbstractPerson.class,
- "INSERT INTO PERSON (PERSON_ID, NAME, PERSON_TYPE) VALUES (3, 'AA', 'EE')"));
-
- context.performGenericQuery(new SQLTemplate(
- PersonNotes.class,
- "INSERT INTO PERSON_NOTES (ID, NOTES, PERSON_ID) VALUES (3, 'AA', 3)"));
-
- SelectQuery query = new SelectQuery(PersonNotes.class);
- query.addPrefetch(PersonNotes.PERSON_PROPERTY).setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
- final PersonNotes note = (PersonNotes) Cayenne.objectForQuery(context, query);
-
- queryBlocker.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals("AA", note.getPerson().getName());
- }
- });
-
- }
-
- public void testSave() throws Exception {
- ClientCompany company = context.newObject(ClientCompany.class);
- company.setName("Boeing");
-
- CustomerRepresentative rep = context.newObject(CustomerRepresentative.class);
- rep.setName("Joe Schmoe");
- rep.setToClientCompany(company);
- rep.setPersonType("C");
-
- Employee employee = context.newObject(Employee.class);
- employee.setName("Our Joe Schmoe");
- employee.setPersonType("E");
-
- context.commitChanges();
- context.invalidateObjects(company, rep, employee);
-
- SelectQuery query = new SelectQuery(CustomerRepresentative.class);
- List<?> reps = context2.performQuery(query);
-
- assertEquals(1, reps.size());
- assertEquals(1, countObjectOfClass(reps, CustomerRepresentative.class));
- }
-
- /**
- * Tests that to-one relationship produces correct subclass.
- */
- public void testEmployeeAddress() throws Exception {
- createEmployeeAddressDataSet();
-
- List<?> addresses = context.performQuery(new SelectQuery(Address.class));
-
- assertEquals(1, addresses.size());
- Address address = (Address) addresses.get(0);
- assertSame(Employee.class, address.getToEmployee().getClass());
- }
-
- /**
- * Tests that to-one relationship produces correct subclass.
- */
- public void testManagerAddress() throws Exception {
- createManagerAddressDataSet();
-
- List<?> addresses = context.performQuery(new SelectQuery(Address.class));
-
- assertEquals(1, addresses.size());
- Address address = (Address) addresses.get(0);
- Employee e = address.getToEmployee();
-
- assertSame(Manager.class, e.getClass());
- }
-
- public void testCAY592() throws Exception {
- createManagerAddressDataSet();
-
- List<?> addresses = context.performQuery(new SelectQuery(Address.class));
-
- assertEquals(1, addresses.size());
- Address address = (Address) addresses.get(0);
- Employee e = address.getToEmployee();
-
- // CAY-592 - make sure modification of the address in a parallel context
- // doesn't mess up the Manager
-
- e = (Employee) Cayenne.objectForPK(context2, e.getObjectId());
- address = e.getAddresses().get(0);
-
- assertSame(e, address.getToEmployee());
- address.setCity("XYZ");
- assertSame(e, address.getToEmployee());
- }
-
- /**
- * Tests that to-one relationship produces correct subclass.
- */
- public void testRepCompany() throws Exception {
- createRepCompanyDataSet();
-
- List<?> companies = context.performQuery(new SelectQuery(ClientCompany.class));
-
- assertEquals(1, companies.size());
- ClientCompany company = (ClientCompany) companies.get(0);
- List<?> reps = company.getRepresentatives();
- assertEquals(1, reps.size());
- assertSame(CustomerRepresentative.class, reps.get(0).getClass());
- }
-
- /**
- * Tests that to-many relationship produces correct subclasses.
- */
- public void testDepartmentEmployees() throws Exception {
- createDepartmentEmployeesDataSet();
-
- List<?> departments = context.performQuery(new SelectQuery(Department.class));
-
- assertEquals(1, departments.size());
- Department dept = (Department) departments.get(0);
- List<?> employees = dept.getEmployees();
- assertEquals(3, employees.size());
- assertEquals(3, countObjectOfClass(employees, Employee.class));
- assertEquals(1, countObjectOfClass(employees, Manager.class));
- }
-
- public void testSelectInheritanceResolving() throws Exception {
- createSelectDataSet();
-
- SelectQuery query = new SelectQuery(AbstractPerson.class);
- List<?> abstractPpl = context.performQuery(query);
- assertEquals(6, abstractPpl.size());
-
- assertEquals(1, countObjectOfClass(abstractPpl, CustomerRepresentative.class));
- assertEquals(5, countObjectOfClass(abstractPpl, Employee.class));
- assertEquals(2, countObjectOfClass(abstractPpl, Manager.class));
- }
-
- /**
- * Test for CAY-1008: Reverse relationships may not be correctly set if inheritance is
- * used.
- */
- public void testCAY1008() {
- RelatedEntity related = context.newObject(RelatedEntity.class);
-
- BaseEntity base = context.newObject(BaseEntity.class);
- base.setToRelatedEntity(related);
-
- assertEquals(1, related.getBaseEntities().size());
- assertEquals(0, related.getSubEntities().size());
-
- SubEntity sub = context.newObject(SubEntity.class);
- sub.setToRelatedEntity(related);
-
- assertEquals(2, related.getBaseEntities().size());
-
- // TODO: andrus 2008/03/28 - this fails...
- // assertEquals(1, related.getSubEntities().size());
- }
-
- /**
- * Test for CAY-1009: Bogus runtime relationships can mess up commit.
- */
- public void testCAY1009() {
-
- // We should have only one relationship. DirectToSubEntity -> SubEntity.
-
- // this fails as a result of 'EntityResolver().applyObjectLayerDefaults()'
- // creating incorrect relationships
- // assertEquals(1, context
- // .getEntityResolver()
- // .getObjEntity("DirectToSubEntity")
- // .getRelationships()
- // .size());
-
- // We should still just have the one mapped relationship, but we in fact now have
- // two:
- // DirectToSubEntity -> BaseEntity and DirectToSubEntity -> SubEntity.
-
- // TODO: andrus 2008/03/28 - this fails...
- // assertEquals(1, context.getEntityResolver().getObjEntity("DirectToSubEntity")
- // .getRelationships().size());
- //
- // DirectToSubEntity direct = context.newObject(DirectToSubEntity.class);
- //
- // SubEntity sub = context.newObject(SubEntity.class);
- // sub.setToDirectToSubEntity(direct);
- //
- // assertEquals(1, direct.getSubEntities().size());
- //
- // context.deleteObject(sub);
- // assertEquals(0, direct.getSubEntities().size());
- }
-
- /**
- * Returns a number of objects of a particular class and subclasses in the list.
- */
- private int countObjectOfClass(List<?> objects, Class<?> aClass) {
- int i = 0;
-
- for (Object next : objects) {
- if (aClass.isAssignableFrom(next.getClass())) {
- i++;
- }
- }
- return i;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListIT.java
new file mode 100644
index 0000000..54a555c
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListIT.java
@@ -0,0 +1,263 @@
+/*****************************************************************
+ * 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.access;
+
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.PersistentObjectList;
+
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class ToManyListIT extends ServerCase {
+
+ @Inject
+ private DataContext context;
+
+ @Inject
+ private DBHelper dbHelper;
+
+ @Override
+ protected void setUpAfterInjection() throws Exception {
+ dbHelper.deleteAll("PAINTING_INFO");
+ dbHelper.deleteAll("PAINTING");
+ dbHelper.deleteAll("ARTIST_EXHIBIT");
+ dbHelper.deleteAll("ARTIST_GROUP");
+ dbHelper.deleteAll("ARTIST");
+ }
+
+ private ToManyList createForNewArtist() {
+ Artist artist = context.newObject(Artist.class);
+ return new ToManyList(artist, Artist.PAINTING_ARRAY_PROPERTY);
+ }
+
+ private ToManyList createForExistingArtist() {
+ Artist artist = context.newObject(Artist.class);
+ artist.setArtistName("aa");
+ context.commitChanges();
+ return new ToManyList(artist, Artist.PAINTING_ARRAY_PROPERTY);
+ }
+
+ public void testNewAddRemove() throws Exception {
+ ToManyList list = createForNewArtist();
+ assertFalse("Expected resolved list when created with a new object", list
+ .isFault());
+ assertEquals(0, list.size());
+
+ Painting p1 = context.newObject(Painting.class);
+ list.add(p1);
+ assertEquals(1, list.size());
+
+ Painting p2 = context.newObject(Painting.class);
+ list.add(p2);
+ assertEquals(2, list.size());
+
+ list.remove(p1);
+ assertEquals(1, list.size());
+ }
+
+ public void testSavedUnresolvedAddRemove() throws Exception {
+ ToManyList list = createForExistingArtist();
+
+ // immediately tag Artist as MODIFIED, since we are messing up with relationship
+ // bypassing normal CayenneDataObject methods
+ list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
+
+ assertTrue("List must be unresolved for an existing object", list.isFault());
+
+ Painting p1 = context.newObject(Painting.class);
+ list.add(p1);
+ assertTrue("List must be unresolved when adding an object...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p1));
+
+ Painting p2 = context.newObject(Painting.class);
+ list.add(p2);
+ assertTrue("List must be unresolved when adding an object...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p2));
+
+ list.remove(p1);
+ assertTrue("List must be unresolved when removing an object...", list.isFault());
+ assertFalse(addedToUnresolved(list).contains(p1));
+
+ // now resolve
+ int size = list.size();
+ assertFalse("List must be resolved after checking a size...", list.isFault());
+ assertEquals(1, size);
+ assertTrue(getValue(list).contains(p2));
+ }
+
+ public void testSavedUnresolvedMerge() throws Exception {
+ ToManyList list = createForExistingArtist();
+
+ Painting p1 = context.newObject(Painting.class);
+ p1.setPaintingTitle("p1");
+
+ // list being tested is a separate copy from
+ // the relationship list that Artist has, so adding a painting
+ // here will not add the painting to the array being tested
+ ((Artist) list.getRelationshipOwner()).addToPaintingArray(p1);
+ context.commitChanges();
+
+ // immediately tag Artist as MODIFIED, since we are messing up with relationship
+ // bypassing normal CayenneDataObject methods
+ list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
+
+ assertTrue("List must be unresolved...", list.isFault());
+ list.add(p1);
+ assertTrue("List must be unresolved when adding an object...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p1));
+
+ Painting p2 = context.newObject(Painting.class);
+ list.add(p2);
+ assertTrue("List must be unresolved when adding an object...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p2));
+
+ // now resolve the list and see how merge worked
+ int size = list.size();
+ assertFalse("List must be resolved after checking a size...", list.isFault());
+ assertEquals(2, size);
+ assertTrue(getValue(list).contains(p2));
+ assertTrue(getValue(list).contains(p1));
+ }
+
+ public void testThrowOutDeleted() throws Exception {
+ ToManyList list = createForExistingArtist();
+
+ Painting p1 = context.newObject(Painting.class);
+ p1.setPaintingTitle("p1");
+ Painting p2 = context.newObject(Painting.class);
+ p2.setPaintingTitle("p2");
+
+ // list being tested is a separate copy from
+ // the relationship list that Artist has, so adding a painting
+ // here will not add the painting to the array being tested
+ ((Artist) list.getRelationshipOwner()).addToPaintingArray(p1);
+ ((Artist) list.getRelationshipOwner()).addToPaintingArray(p2);
+ context.commitChanges();
+
+ // immediately tag Artist as MODIFIED, since we are messing up with relationship
+ // bypassing normal CayenneDataObject methods
+ list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
+
+ assertTrue("List must be unresolved...", list.isFault());
+ list.add(p1);
+ list.add(p2);
+ assertTrue("List must be unresolved when adding an object...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p2));
+ assertTrue(addedToUnresolved(list).contains(p1));
+
+ // now delete p2 and resolve list
+ ((Artist) list.getRelationshipOwner()).removeFromPaintingArray(p2);
+ context.deleteObjects(p2);
+ context.commitChanges();
+
+ assertTrue("List must be unresolved...", list.isFault());
+ assertTrue(
+ "List must be unresolved when an object was deleted externally...",
+ list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p2));
+ assertTrue(addedToUnresolved(list).contains(p1));
+
+ // now resolve the list and see how merge worked
+ int size = list.size();
+ assertFalse("List must be resolved after checking a size...", list.isFault());
+ assertEquals("Deleted object must have been purged...", 1, size);
+ assertTrue(getValue(list).contains(p1));
+ assertFalse("Deleted object must have been purged...", getValue(list)
+ .contains(p2));
+ }
+
+ public void testRealRelationship() throws Exception {
+ Artist artist = context.newObject(Artist.class);
+ artist.setArtistName("aaa");
+
+ Painting p1 = context.newObject(Painting.class);
+ p1.setPaintingTitle("p1");
+
+ context.commitChanges();
+ context.invalidateObjects(artist);
+
+ ToManyList list = (ToManyList) artist.getPaintingArray();
+ assertTrue("List must be unresolved...", list.isFault());
+
+ Painting p2 = context.newObject(Painting.class);
+ p2.setPaintingTitle("p2");
+
+ artist.addToPaintingArray(p1);
+ artist.addToPaintingArray(p2);
+ assertTrue("List must be unresolved...", list.isFault());
+
+ context.commitChanges();
+
+ assertTrue("List must be unresolved...", list.isFault());
+
+ int size = list.size();
+ assertFalse("List must be resolved...", list.isFault());
+ assertTrue(list.contains(p1));
+ assertTrue(list.contains(p2));
+ assertEquals(2, size);
+ }
+
+ public void testRealRelationshipRollback() throws Exception {
+ Artist artist = context.newObject(Artist.class);
+ artist.setArtistName("aaa");
+
+ Painting p1 = context.newObject(Painting.class);
+ p1.setPaintingTitle("p1");
+ artist.addToPaintingArray(p1);
+ context.commitChanges();
+ context.invalidateObjects(artist);
+
+ ToManyList list = (ToManyList) artist.getPaintingArray();
+ assertTrue("List must be unresolved...", list.isFault());
+
+ Painting p2 = context.newObject(Painting.class);
+
+ artist.addToPaintingArray(p2);
+ assertTrue("List must be unresolved...", list.isFault());
+ assertTrue(addedToUnresolved(list).contains(p2));
+
+ context.rollbackChanges();
+
+ assertTrue("List must be unresolved...", list.isFault());
+
+ // call to "contains" must trigger list resolution
+ assertTrue(list.contains(p1));
+ assertFalse(list.contains(p2));
+ assertFalse("List must be resolved...", list.isFault());
+ }
+
+ private List<?> getValue(ToManyList list) {
+ return (List<?>) list.getValueDirectly();
+ }
+
+ private LinkedList<?> addedToUnresolved(ToManyList list) throws Exception {
+ Field f = PersistentObjectList.class.getDeclaredField("addedToUnresolved");
+ f.setAccessible(true);
+ return (LinkedList<?>) f.get(list);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListTest.java
deleted file mode 100644
index 1cc84e1..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/ToManyListTest.java
+++ /dev/null
@@ -1,263 +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.access;
-
-import java.lang.reflect.Field;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.PersistentObjectList;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class ToManyListTest extends ServerCase {
-
- @Inject
- private DataContext context;
-
- @Inject
- private DBHelper dbHelper;
-
- @Override
- protected void setUpAfterInjection() throws Exception {
- dbHelper.deleteAll("PAINTING_INFO");
- dbHelper.deleteAll("PAINTING");
- dbHelper.deleteAll("ARTIST_EXHIBIT");
- dbHelper.deleteAll("ARTIST_GROUP");
- dbHelper.deleteAll("ARTIST");
- }
-
- private ToManyList createForNewArtist() {
- Artist artist = context.newObject(Artist.class);
- return new ToManyList(artist, Artist.PAINTING_ARRAY_PROPERTY);
- }
-
- private ToManyList createForExistingArtist() {
- Artist artist = context.newObject(Artist.class);
- artist.setArtistName("aa");
- context.commitChanges();
- return new ToManyList(artist, Artist.PAINTING_ARRAY_PROPERTY);
- }
-
- public void testNewAddRemove() throws Exception {
- ToManyList list = createForNewArtist();
- assertFalse("Expected resolved list when created with a new object", list
- .isFault());
- assertEquals(0, list.size());
-
- Painting p1 = context.newObject(Painting.class);
- list.add(p1);
- assertEquals(1, list.size());
-
- Painting p2 = context.newObject(Painting.class);
- list.add(p2);
- assertEquals(2, list.size());
-
- list.remove(p1);
- assertEquals(1, list.size());
- }
-
- public void testSavedUnresolvedAddRemove() throws Exception {
- ToManyList list = createForExistingArtist();
-
- // immediately tag Artist as MODIFIED, since we are messing up with relationship
- // bypassing normal CayenneDataObject methods
- list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
-
- assertTrue("List must be unresolved for an existing object", list.isFault());
-
- Painting p1 = context.newObject(Painting.class);
- list.add(p1);
- assertTrue("List must be unresolved when adding an object...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p1));
-
- Painting p2 = context.newObject(Painting.class);
- list.add(p2);
- assertTrue("List must be unresolved when adding an object...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p2));
-
- list.remove(p1);
- assertTrue("List must be unresolved when removing an object...", list.isFault());
- assertFalse(addedToUnresolved(list).contains(p1));
-
- // now resolve
- int size = list.size();
- assertFalse("List must be resolved after checking a size...", list.isFault());
- assertEquals(1, size);
- assertTrue(getValue(list).contains(p2));
- }
-
- public void testSavedUnresolvedMerge() throws Exception {
- ToManyList list = createForExistingArtist();
-
- Painting p1 = context.newObject(Painting.class);
- p1.setPaintingTitle("p1");
-
- // list being tested is a separate copy from
- // the relationship list that Artist has, so adding a painting
- // here will not add the painting to the array being tested
- ((Artist) list.getRelationshipOwner()).addToPaintingArray(p1);
- context.commitChanges();
-
- // immediately tag Artist as MODIFIED, since we are messing up with relationship
- // bypassing normal CayenneDataObject methods
- list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
-
- assertTrue("List must be unresolved...", list.isFault());
- list.add(p1);
- assertTrue("List must be unresolved when adding an object...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p1));
-
- Painting p2 = context.newObject(Painting.class);
- list.add(p2);
- assertTrue("List must be unresolved when adding an object...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p2));
-
- // now resolve the list and see how merge worked
- int size = list.size();
- assertFalse("List must be resolved after checking a size...", list.isFault());
- assertEquals(2, size);
- assertTrue(getValue(list).contains(p2));
- assertTrue(getValue(list).contains(p1));
- }
-
- public void testThrowOutDeleted() throws Exception {
- ToManyList list = createForExistingArtist();
-
- Painting p1 = context.newObject(Painting.class);
- p1.setPaintingTitle("p1");
- Painting p2 = context.newObject(Painting.class);
- p2.setPaintingTitle("p2");
-
- // list being tested is a separate copy from
- // the relationship list that Artist has, so adding a painting
- // here will not add the painting to the array being tested
- ((Artist) list.getRelationshipOwner()).addToPaintingArray(p1);
- ((Artist) list.getRelationshipOwner()).addToPaintingArray(p2);
- context.commitChanges();
-
- // immediately tag Artist as MODIFIED, since we are messing up with relationship
- // bypassing normal CayenneDataObject methods
- list.getRelationshipOwner().setPersistenceState(PersistenceState.MODIFIED);
-
- assertTrue("List must be unresolved...", list.isFault());
- list.add(p1);
- list.add(p2);
- assertTrue("List must be unresolved when adding an object...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p2));
- assertTrue(addedToUnresolved(list).contains(p1));
-
- // now delete p2 and resolve list
- ((Artist) list.getRelationshipOwner()).removeFromPaintingArray(p2);
- context.deleteObjects(p2);
- context.commitChanges();
-
- assertTrue("List must be unresolved...", list.isFault());
- assertTrue(
- "List must be unresolved when an object was deleted externally...",
- list.isFault());
- assertTrue(addedToUnresolved(list).contains(p2));
- assertTrue(addedToUnresolved(list).contains(p1));
-
- // now resolve the list and see how merge worked
- int size = list.size();
- assertFalse("List must be resolved after checking a size...", list.isFault());
- assertEquals("Deleted object must have been purged...", 1, size);
- assertTrue(getValue(list).contains(p1));
- assertFalse("Deleted object must have been purged...", getValue(list)
- .contains(p2));
- }
-
- public void testRealRelationship() throws Exception {
- Artist artist = context.newObject(Artist.class);
- artist.setArtistName("aaa");
-
- Painting p1 = context.newObject(Painting.class);
- p1.setPaintingTitle("p1");
-
- context.commitChanges();
- context.invalidateObjects(artist);
-
- ToManyList list = (ToManyList) artist.getPaintingArray();
- assertTrue("List must be unresolved...", list.isFault());
-
- Painting p2 = context.newObject(Painting.class);
- p2.setPaintingTitle("p2");
-
- artist.addToPaintingArray(p1);
- artist.addToPaintingArray(p2);
- assertTrue("List must be unresolved...", list.isFault());
-
- context.commitChanges();
-
- assertTrue("List must be unresolved...", list.isFault());
-
- int size = list.size();
- assertFalse("List must be resolved...", list.isFault());
- assertTrue(list.contains(p1));
- assertTrue(list.contains(p2));
- assertEquals(2, size);
- }
-
- public void testRealRelationshipRollback() throws Exception {
- Artist artist = context.newObject(Artist.class);
- artist.setArtistName("aaa");
-
- Painting p1 = context.newObject(Painting.class);
- p1.setPaintingTitle("p1");
- artist.addToPaintingArray(p1);
- context.commitChanges();
- context.invalidateObjects(artist);
-
- ToManyList list = (ToManyList) artist.getPaintingArray();
- assertTrue("List must be unresolved...", list.isFault());
-
- Painting p2 = context.newObject(Painting.class);
-
- artist.addToPaintingArray(p2);
- assertTrue("List must be unresolved...", list.isFault());
- assertTrue(addedToUnresolved(list).contains(p2));
-
- context.rollbackChanges();
-
- assertTrue("List must be unresolved...", list.isFault());
-
- // call to "contains" must trigger list resolution
- assertTrue(list.contains(p1));
- assertFalse(list.contains(p2));
- assertFalse("List must be resolved...", list.isFault());
- }
-
- private List<?> getValue(ToManyList list) {
- return (List<?>) list.getValueDirectly();
- }
-
- private LinkedList<?> addedToUnresolved(ToManyList list) throws Exception {
- Field f = PersistentObjectList.class.getDeclaredField("addedToUnresolved");
- f.setAccessible(true);
- return (LinkedList<?>) f.get(list);
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/TransactionThreadIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/TransactionThreadIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/TransactionThreadIT.java
new file mode 100644
index 0000000..eb290fd
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/TransactionThreadIT.java
@@ -0,0 +1,118 @@
+/*****************************************************************
+ * 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.access;
+
+import java.sql.Connection;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.tx.BaseTransaction;
+import org.apache.cayenne.tx.CayenneTransaction;
+import org.apache.cayenne.tx.Transaction;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class TransactionThreadIT extends ServerCase {
+
+ @Inject
+ private DataContext context;
+
+ @Inject
+ protected DBHelper dbHelper;
+
+ @Inject
+ private JdbcEventLogger logger;
+
+ @Override
+ protected void setUpAfterInjection() throws Exception {
+ dbHelper.deleteAll("PAINTING_INFO");
+ dbHelper.deleteAll("PAINTING");
+ dbHelper.deleteAll("ARTIST_EXHIBIT");
+ dbHelper.deleteAll("ARTIST_GROUP");
+ dbHelper.deleteAll("ARTIST");
+ }
+
+ public void testThreadConnectionReuseOnSelect() throws Exception {
+
+ ConnectionCounterTx t = new ConnectionCounterTx(new CayenneTransaction(logger));
+ BaseTransaction.bindThreadTransaction(t);
+
+ try {
+
+ SelectQuery q1 = new SelectQuery(Artist.class);
+ context.performQuery(q1);
+ assertEquals(1, t.connectionCount);
+
+ // delegate will fail if the second query opens a new connection
+ SelectQuery q2 = new SelectQuery(Artist.class);
+ context.performQuery(q2);
+
+ } finally {
+ BaseTransaction.bindThreadTransaction(null);
+ t.commit();
+ }
+ }
+
+ class ConnectionCounterTx implements Transaction {
+
+ private Transaction delegate;
+ int connectionCount;
+
+ ConnectionCounterTx(Transaction delegate) {
+ this.delegate = delegate;
+ }
+
+ public void begin() {
+ delegate.begin();
+ }
+
+ public void commit() {
+ delegate.commit();
+ }
+
+ public void rollback() {
+ delegate.rollback();
+ }
+
+ public void setRollbackOnly() {
+ delegate.setRollbackOnly();
+ }
+
+ public boolean isRollbackOnly() {
+ return delegate.isRollbackOnly();
+ }
+
+ public Connection getConnection(String name) {
+ return delegate.getConnection(name);
+ }
+
+ public void addConnection(String name, Connection connection) {
+ if (connectionCount++ > 0) {
+ fail("Invalid attempt to add connection");
+ }
+
+ delegate.addConnection(name, connection);
+ }
+ }
+}