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:20 UTC
[32/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/DataContextPrefetchMultistepTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepTest.java
deleted file mode 100644
index 59100e1..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepTest.java
+++ /dev/null
@@ -1,311 +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.Timestamp;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.Fault;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.ValueHolder;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-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.ArtistExhibit;
-import org.apache.cayenne.testdo.testmap.Exhibit;
-import org.apache.cayenne.testdo.testmap.Gallery;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
-public class DataContextPrefetchMultistepTest extends ServerCase {
-
- @Inject
- protected DataContext context;
-
- @Inject
- protected DBHelper dbHelper;
-
- protected TableHelper tArtist;
- protected TableHelper tExhibit;
- protected TableHelper tGallery;
- protected TableHelper tArtistExhibit;
-
- @Override
- protected void setUpAfterInjection() throws Exception {
- dbHelper.deleteAll("PAINTING_INFO");
- dbHelper.deleteAll("PAINTING");
- dbHelper.deleteAll("ARTIST_EXHIBIT");
- dbHelper.deleteAll("ARTIST_GROUP");
- dbHelper.deleteAll("ARTIST");
- dbHelper.deleteAll("EXHIBIT");
- dbHelper.deleteAll("GALLERY");
-
- tArtist = new TableHelper(dbHelper, "ARTIST");
- tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
- tExhibit = new TableHelper(dbHelper, "EXHIBIT");
- tExhibit.setColumns("EXHIBIT_ID", "GALLERY_ID", "OPENING_DATE", "CLOSING_DATE");
-
- tArtistExhibit = new TableHelper(dbHelper, "ARTIST_EXHIBIT");
- tArtistExhibit.setColumns("ARTIST_ID", "EXHIBIT_ID");
-
- tGallery = new TableHelper(dbHelper, "GALLERY");
- tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
- }
-
- protected void createTwoArtistsWithExhibitsDataSet() throws Exception {
- tArtist.insert(11, "artist2");
- tArtist.insert(101, "artist3");
-
- tGallery.insert(25, "gallery1");
- tGallery.insert(31, "gallery2");
- tGallery.insert(45, "gallery3");
-
- Timestamp now = new Timestamp(System.currentTimeMillis());
-
- tExhibit.insert(1, 25, now, now);
- tExhibit.insert(2, 31, now, now);
- tExhibit.insert(3, 45, now, now);
- tExhibit.insert(4, 25, now, now);
-
- tArtistExhibit.insert(11, 2);
- tArtistExhibit.insert(11, 4);
- tArtistExhibit.insert(101, 1);
- tArtistExhibit.insert(101, 2);
- tArtistExhibit.insert(101, 4);
- }
-
- protected void createGalleriesAndArtists() throws Exception {
- tArtist.insert(11, "artist2");
- tArtist.insert(101, "artist3");
-
- tGallery.insert(25, "gallery1");
- tGallery.insert(31, "gallery2");
- tGallery.insert(45, "gallery3");
- }
-
- public void testToManyToManyFirstStepUnresolved() throws Exception {
-
- createTwoArtistsWithExhibitsDataSet();
-
- // since objects for the phantom prefetches are not retained explicitly, they may
- // get garbage collected, and we won't be able to detect them
- // so ensure ObjectStore uses a regular map just for this test
-
- context.getObjectStore().objectMap = new HashMap<Object, Persistent>();
-
- // Check the target ArtistExhibit objects do not exist yet
-
- Map<String, Object> id1 = new HashMap<String, Object>();
- id1.put("ARTIST_ID", 11);
- id1.put("EXHIBIT_ID", 2);
- ObjectId oid1 = new ObjectId("ArtistExhibit", id1);
-
- Map<String, Object> id2 = new HashMap<String, Object>();
- id2.put("ARTIST_ID", 101);
- id2.put("EXHIBIT_ID", 2);
- ObjectId oid2 = new ObjectId("ArtistExhibit", id2);
-
- assertNull(context.getGraphManager().getNode(oid1));
- assertNull(context.getGraphManager().getNode(oid2));
-
- Expression e = Expression.fromString("galleryName = $name");
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class, e.expWithParameters(Collections
- .singletonMap("name", "gallery2")));
- q.addPrefetch("exhibitArray.artistExhibitArray");
-
- List<Gallery> galleries = context.select(q);
- assertEquals(1, galleries.size());
-
- Gallery g2 = galleries.get(0);
-
- // this relationship wasn't explicitly prefetched....
- Object list = g2.readPropertyDirectly("exhibitArray");
- assertTrue(list instanceof Fault);
-
- // however the target objects must be resolved
- ArtistExhibit ae1 = (ArtistExhibit) context.getGraphManager().getNode(oid1);
- ArtistExhibit ae2 = (ArtistExhibit) context.getGraphManager().getNode(oid2);
-
- assertNotNull(ae1);
- assertNotNull(ae2);
- assertEquals(PersistenceState.COMMITTED, ae1.getPersistenceState());
- assertEquals(PersistenceState.COMMITTED, ae2.getPersistenceState());
- }
-
- public void testToManyToManyFirstStepResolved() throws Exception {
-
- createTwoArtistsWithExhibitsDataSet();
-
- Expression e = Expression.fromString("galleryName = $name");
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class, e.expWithParameters(Collections
- .singletonMap("name", "gallery2")));
- q.addPrefetch("exhibitArray");
- q.addPrefetch("exhibitArray.artistExhibitArray");
-
- List<Gallery> galleries = context.select(q);
- assertEquals(1, galleries.size());
-
- Gallery g2 = galleries.get(0);
-
- // this relationship should be resolved
- assertTrue(g2.readPropertyDirectly("exhibitArray") instanceof ValueHolder);
- List<Exhibit> exhibits = (List<Exhibit>) g2.readPropertyDirectly("exhibitArray");
- assertFalse(((ValueHolder) exhibits).isFault());
- assertEquals(1, exhibits.size());
-
- Exhibit e1 = exhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, e1.getPersistenceState());
-
- // this to-many must also be resolved
- assertTrue(e1.readPropertyDirectly("artistExhibitArray") instanceof ValueHolder);
- List<ArtistExhibit> aexhibits = (List<ArtistExhibit>) e1
- .readPropertyDirectly("artistExhibitArray");
- assertFalse(((ValueHolder) aexhibits).isFault());
- assertEquals(1, exhibits.size());
-
- ArtistExhibit ae1 = aexhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, ae1.getPersistenceState());
- }
-
- public void testMixedPrefetch1() throws Exception {
-
- createTwoArtistsWithExhibitsDataSet();
-
- Expression e = Expression.fromString("galleryName = $name");
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class, e.expWithParameters(Collections
- .singletonMap("name", "gallery2")));
- q.addPrefetch("exhibitArray").setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
- q.addPrefetch("exhibitArray.artistExhibitArray");
-
- List<Gallery> galleries = context.select(q);
- assertEquals(1, galleries.size());
-
- Gallery g2 = galleries.get(0);
-
- // this relationship should be resolved
- assertTrue(g2.readPropertyDirectly("exhibitArray") instanceof ValueHolder);
- List<Exhibit> exhibits = (List<Exhibit>) g2.readPropertyDirectly("exhibitArray");
- assertFalse(((ValueHolder) exhibits).isFault());
- assertEquals(1, exhibits.size());
-
- Exhibit e1 = exhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, e1.getPersistenceState());
-
- // this to-many must also be resolved
- assertTrue(e1.readPropertyDirectly("artistExhibitArray") instanceof ValueHolder);
- List<ArtistExhibit> aexhibits = (List<ArtistExhibit>) e1
- .readPropertyDirectly("artistExhibitArray");
- assertFalse(((ValueHolder) aexhibits).isFault());
- assertEquals(2, aexhibits.size());
-
- ArtistExhibit ae1 = aexhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, ae1.getPersistenceState());
- }
-
- public void testMixedPrefetch2() throws Exception {
-
- createTwoArtistsWithExhibitsDataSet();
-
- Expression e = Expression.fromString("galleryName = $name");
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class, e.expWithParameters(Collections
- .singletonMap("name", "gallery2")));
-
- // reverse the order of prefetches compared to the previous test
- q.addPrefetch("exhibitArray");
- q.addPrefetch("exhibitArray.artistExhibitArray").setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
- List<Gallery> galleries = context.select(q);
- assertEquals(1, galleries.size());
-
- Gallery g2 = galleries.get(0);
-
- // this relationship should be resolved
- assertTrue(g2.readPropertyDirectly("exhibitArray") instanceof ValueHolder);
- List<Exhibit> exhibits = (List<Exhibit>) g2.readPropertyDirectly("exhibitArray");
- assertFalse(((ValueHolder) exhibits).isFault());
- assertEquals(1, exhibits.size());
-
- Exhibit e1 = exhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, e1.getPersistenceState());
-
- // this to-many must also be resolved
- assertTrue(e1.readPropertyDirectly("artistExhibitArray") instanceof ValueHolder);
- List<ArtistExhibit> aexhibits = (List<ArtistExhibit>) e1
- .readPropertyDirectly("artistExhibitArray");
- assertFalse(((ValueHolder) aexhibits).isFault());
- assertEquals(2, aexhibits.size());
-
- ArtistExhibit ae1 = aexhibits.get(0);
- assertEquals(PersistenceState.COMMITTED, ae1.getPersistenceState());
- }
-
- public void testToManyToOne_EmptyToMany() throws Exception {
-
- createGalleriesAndArtists();
-
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class, Gallery.GALLERY_NAME.eq("gallery2"));
- q.addPrefetch(Gallery.PAINTING_ARRAY.disjoint());
- q.addPrefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).disjoint());
-
- List<Gallery> galleries = context.select(q);
- assertEquals(1, galleries.size());
-
- Gallery g2 = galleries.get(0);
-
- // this relationship should be resolved
- assertTrue(g2.readPropertyDirectly(Gallery.PAINTING_ARRAY.getName()) instanceof ValueHolder);
- List<Painting> exhibits = (List<Painting>) g2.readPropertyDirectly(Gallery.PAINTING_ARRAY.getName());
- assertFalse(((ValueHolder) exhibits).isFault());
- assertEquals(0, exhibits.size());
- }
-
- public void testToManyToOne_EmptyToMany_NoRootQualifier() throws Exception {
-
- createGalleriesAndArtists();
-
- SelectQuery<Gallery> q = SelectQuery.query(Gallery.class);
- q.addPrefetch(Gallery.PAINTING_ARRAY.disjoint());
- q.addPrefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).disjoint());
-
- List<Gallery> galleries = context.select(q);
- assertEquals(3, galleries.size());
-
- Gallery g = galleries.get(0);
-
- // this relationship should be resolved
- assertTrue(g.readPropertyDirectly(Gallery.PAINTING_ARRAY.getName()) instanceof ValueHolder);
- List<Painting> exhibits = (List<Painting>) g.readPropertyDirectly(Gallery.PAINTING_ARRAY.getName());
- assertFalse(((ValueHolder) exhibits).isFault());
- assertEquals(0, exhibits.size());
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapIT.java
new file mode 100644
index 0000000..dd6e52e
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapIT.java
@@ -0,0 +1,122 @@
+/*****************************************************************
+ * 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.di.Inject;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.PrefetchTreeNode;
+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;
+
+import java.util.List;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextPrefetchQualifierOverlapIT 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("PAINTING1");
+ dbHelper.deleteAll("ARTIST_EXHIBIT");
+ dbHelper.deleteAll("ARTIST_GROUP");
+ dbHelper.deleteAll("ARTIST");
+ }
+
+ private void createTwoArtistsThreePaintingsDataSet() throws Exception {
+ TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
+ tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
+
+ TableHelper tPainting = new TableHelper(dbHelper, "PAINTING");
+ tPainting.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID");
+
+ tArtist.insert(1, "A1");
+ tArtist.insert(2, "A2");
+
+ tPainting.insert(1, "ABC", 1);
+ tPainting.insert(2, "ABD", 1);
+ tPainting.insert(3, "ACC", 1);
+ }
+
+ public void testToManyDisjointOverlappingQualifierWithInnerJoin() throws Exception {
+ createTwoArtistsThreePaintingsDataSet();
+
+ SelectQuery query = new SelectQuery(Artist.class);
+ query.andQualifier(ExpressionFactory
+ .likeExp("paintingArray.paintingTitle", "AB%"));
+ query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+ PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
+
+ List<Artist> result = context.performQuery(query);
+ assertEquals(1, result.size());
+
+ Artist a = result.get(0);
+ assertEquals(3, a.getPaintingArray().size());
+ }
+
+ public void testToManyJointOverlappingQualifierWithInnerJoin() throws Exception {
+ createTwoArtistsThreePaintingsDataSet();
+
+ SelectQuery query = new SelectQuery(Artist.class);
+ query.andQualifier(ExpressionFactory
+ .likeExp("paintingArray.paintingTitle", "AB%"));
+ query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+ PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+ List<Artist> result = context.performQuery(query);
+ assertEquals(1, result.size());
+
+ Artist a = result.get(0);
+ assertEquals(3, a.getPaintingArray().size());
+ }
+
+ public void testToManyJointOverlappingQualifierWithOuterJoin() throws Exception {
+ createTwoArtistsThreePaintingsDataSet();
+
+ SelectQuery query = new SelectQuery(Artist.class);
+ query.andQualifier(ExpressionFactory.likeExp(
+ "paintingArray+.paintingTitle",
+ "AB%"));
+ query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
+ PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+
+ query.orQualifier(ExpressionFactory.likeExp("artistName", "A%"));
+ query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
+
+ List<Artist> result = context.performQuery(query);
+ assertEquals(2, result.size());
+
+ Artist a = result.get(0);
+ assertEquals(3, a.getPaintingArray().size());
+
+ Artist a1 = result.get(1);
+ assertEquals(0, a1.getPaintingArray().size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapTest.java
deleted file mode 100644
index 97bf573..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchQualifierOverlapTest.java
+++ /dev/null
@@ -1,122 +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.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.PrefetchTreeNode;
-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 DataContextPrefetchQualifierOverlapTest 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("PAINTING1");
- dbHelper.deleteAll("ARTIST_EXHIBIT");
- dbHelper.deleteAll("ARTIST_GROUP");
- dbHelper.deleteAll("ARTIST");
- }
-
- private void createTwoArtistsThreePaintingsDataSet() throws Exception {
- TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
- tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
- TableHelper tPainting = new TableHelper(dbHelper, "PAINTING");
- tPainting.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID");
-
- tArtist.insert(1, "A1");
- tArtist.insert(2, "A2");
-
- tPainting.insert(1, "ABC", 1);
- tPainting.insert(2, "ABD", 1);
- tPainting.insert(3, "ACC", 1);
- }
-
- public void testToManyDisjointOverlappingQualifierWithInnerJoin() throws Exception {
- createTwoArtistsThreePaintingsDataSet();
-
- SelectQuery query = new SelectQuery(Artist.class);
- query.andQualifier(ExpressionFactory
- .likeExp("paintingArray.paintingTitle", "AB%"));
- query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
- PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
-
- List<Artist> result = context.performQuery(query);
- assertEquals(1, result.size());
-
- Artist a = result.get(0);
- assertEquals(3, a.getPaintingArray().size());
- }
-
- public void testToManyJointOverlappingQualifierWithInnerJoin() throws Exception {
- createTwoArtistsThreePaintingsDataSet();
-
- SelectQuery query = new SelectQuery(Artist.class);
- query.andQualifier(ExpressionFactory
- .likeExp("paintingArray.paintingTitle", "AB%"));
- query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
- List<Artist> result = context.performQuery(query);
- assertEquals(1, result.size());
-
- Artist a = result.get(0);
- assertEquals(3, a.getPaintingArray().size());
- }
-
- public void testToManyJointOverlappingQualifierWithOuterJoin() throws Exception {
- createTwoArtistsThreePaintingsDataSet();
-
- SelectQuery query = new SelectQuery(Artist.class);
- query.andQualifier(ExpressionFactory.likeExp(
- "paintingArray+.paintingTitle",
- "AB%"));
- query.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY).setSemantics(
- PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
-
- query.orQualifier(ExpressionFactory.likeExp("artistName", "A%"));
- query.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-
- List<Artist> result = context.performQuery(query);
- assertEquals(2, result.size());
-
- Artist a = result.get(0);
- assertEquals(3, a.getPaintingArray().size());
-
- Artist a1 = result.get(1);
- assertEquals(0, a1.getPaintingArray().size());
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchTest.java
deleted file mode 100644
index 4e887e6..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPrefetchTest.java
+++ /dev/null
@@ -1,801 +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.Timestamp;
-import java.sql.Types;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.ValueHolder;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.exp.Property;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.QueryCacheStrategy;
-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.ArtGroup;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.ArtistExhibit;
-import org.apache.cayenne.testdo.testmap.Painting;
-import org.apache.cayenne.testdo.testmap.PaintingInfo;
-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 DataContextPrefetchTest extends ServerCase {
-
- @Inject
- protected DataContext context;
-
- @Inject
- protected DBHelper dbHelper;
-
- @Inject
- protected DataChannelInterceptor queryInterceptor;
-
- protected TableHelper tArtist;
- protected TableHelper tPainting;
- protected TableHelper tPaintingInfo;
- protected TableHelper tExhibit;
- protected TableHelper tGallery;
- protected TableHelper tArtistExhibit;
- protected TableHelper tArtistGroup;
- protected TableHelper tArtGroup;
-
-
- @Override
- protected void setUpAfterInjection() throws Exception {
- dbHelper.deleteAll("PAINTING_INFO");
- dbHelper.deleteAll("PAINTING");
- dbHelper.deleteAll("ARTIST_EXHIBIT");
- dbHelper.deleteAll("ARTIST_GROUP");
- dbHelper.deleteAll("ARTGROUP");
-
- dbHelper.deleteAll("ARTIST");
- dbHelper.deleteAll("EXHIBIT");
- dbHelper.deleteAll("GALLERY");
-
- tArtist = new TableHelper(dbHelper, "ARTIST");
- tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
-
- tPainting = new TableHelper(dbHelper, "PAINTING");
- tPainting.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "ESTIMATED_PRICE").setColumnTypes(
- Types.INTEGER, Types.VARCHAR, Types.BIGINT, Types.DECIMAL);
-
- tPaintingInfo = new TableHelper(dbHelper, "PAINTING_INFO");
- tPaintingInfo.setColumns("PAINTING_ID", "TEXT_REVIEW");
-
- tExhibit = new TableHelper(dbHelper, "EXHIBIT");
- tExhibit.setColumns("EXHIBIT_ID", "GALLERY_ID", "OPENING_DATE", "CLOSING_DATE");
-
- tArtistExhibit = new TableHelper(dbHelper, "ARTIST_EXHIBIT");
- tArtistExhibit.setColumns("ARTIST_ID", "EXHIBIT_ID");
-
- tGallery = new TableHelper(dbHelper, "GALLERY");
- tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
-
- tArtistGroup = new TableHelper(dbHelper, "ARTIST_GROUP");
- tArtistGroup.setColumns("ARTIST_ID", "GROUP_ID");
-
- tArtGroup = new TableHelper(dbHelper, "ARTGROUP");
- tArtGroup.setColumns("GROUP_ID", "NAME");
- }
-
- protected void createTwoArtistsAndTwoPaintingsDataSet() throws Exception {
- tArtist.insert(11, "artist2");
- tArtist.insert(101, "artist3");
- tPainting.insert(6, "p_artist3", 101, 1000);
- tPainting.insert(7, "p_artist2", 11, 2000);
- }
-
- protected void createArtistWithTwoPaintingsAndTwoInfosDataSet() throws Exception {
- tArtist.insert(11, "artist2");
-
- tPainting.insert(6, "p_artist2", 11, 1000);
- tPainting.insert(7, "p_artist3", 11, 2000);
-
- tPaintingInfo.insert(6, "xYs");
- }
-
- protected void createTwoArtistsWithExhibitsDataSet() throws Exception {
- tArtist.insert(11, "artist2");
- tArtist.insert(101, "artist3");
-
- tGallery.insert(25, "gallery1");
- tGallery.insert(31, "gallery2");
- tGallery.insert(45, "gallery3");
-
- Timestamp now = new Timestamp(System.currentTimeMillis());
-
- tExhibit.insert(1, 25, now, now);
- tExhibit.insert(2, 31, now, now);
- tExhibit.insert(3, 45, now, now);
- tExhibit.insert(4, 25, now, now);
-
- tArtistExhibit.insert(11, 2);
- tArtistExhibit.insert(11, 4);
- tArtistExhibit.insert(101, 1);
- tArtistExhibit.insert(101, 3);
- tArtistExhibit.insert(101, 4);
- }
-
- public void testPrefetchToMany_ViaProperty() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- SelectQuery<Artist> q = new SelectQuery<Artist>(Artist.class);
- q.addPrefetch(Artist.PAINTING_ARRAY.disjoint());
-
- final List<Artist> artists = context.select(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
-
- assertEquals(2, artists.size());
-
- for (int i = 0; i < 2; i++) {
- Artist a = artists.get(i);
- List<?> toMany = (List<?>) a.readPropertyDirectly("paintingArray");
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(1, toMany.size());
-
- Painting p = (Painting) toMany.get(0);
- assertEquals("Invalid prefetched painting:" + p, "p_" + a.getArtistName(), p.getPaintingTitle());
- }
- }
- });
- }
-
- public void testPrefetchToMany_WithQualfier() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("name1", "artist2");
- params.put("name2", "artist3");
- Expression e = Expression.fromString("artistName = $name1 or artistName = $name2");
- SelectQuery q = new SelectQuery("Artist", e.expWithParameters(params));
- q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
-
- final List<Artist> artists = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
-
- assertEquals(2, artists.size());
-
- Artist a1 = artists.get(0);
- List<?> toMany = (List<?>) a1.readPropertyDirectly(Artist.PAINTING_ARRAY_PROPERTY);
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(1, toMany.size());
-
- Painting p1 = (Painting) toMany.get(0);
- assertEquals("p_" + a1.getArtistName(), p1.getPaintingTitle());
-
- Artist a2 = artists.get(1);
- List<?> toMany2 = (List<?>) a2.readPropertyDirectly(Artist.PAINTING_ARRAY_PROPERTY);
- assertNotNull(toMany2);
- assertFalse(((ValueHolder) toMany2).isFault());
- assertEquals(1, toMany2.size());
-
- Painting p2 = (Painting) toMany2.get(0);
- assertEquals("p_" + a2.getArtistName(), p2.getPaintingTitle());
- }
- });
- }
-
- public void testPrefetchToManyNoQualifier() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- SelectQuery q = new SelectQuery(Artist.class);
- q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
-
- final List<Artist> artists = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
-
- assertEquals(2, artists.size());
-
- for (int i = 0; i < 2; i++) {
- Artist a = artists.get(i);
- List<?> toMany = (List<?>) a.readPropertyDirectly("paintingArray");
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(1, toMany.size());
-
- Painting p = (Painting) toMany.get(0);
- assertEquals("Invalid prefetched painting:" + p, "p_" + a.getArtistName(), p.getPaintingTitle());
- }
- }
- });
- }
-
- /**
- * Test that a to-many relationship is initialized when a target entity has
- * a compound PK only partially involved in relationship.
- */
- public void testPrefetchToMany_OnJoinTableDisjoinedPrefetch() throws Exception {
-
- createTwoArtistsWithExhibitsDataSet();
-
- SelectQuery q = new SelectQuery(Artist.class);
- q.addPrefetch(Artist.ARTIST_EXHIBIT_ARRAY_PROPERTY).setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
- q.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-
- final List<Artist> artists = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(2, artists.size());
-
- Artist a1 = artists.get(0);
- assertEquals("artist2", a1.getArtistName());
- List<?> toMany = (List<?>) a1.readPropertyDirectly(Artist.ARTIST_EXHIBIT_ARRAY_PROPERTY);
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(2, toMany.size());
-
- ArtistExhibit artistExhibit = (ArtistExhibit) toMany.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit.getPersistenceState());
- assertSame(a1, artistExhibit.getToArtist());
-
- Artist a2 = artists.get(1);
- assertEquals("artist3", a2.getArtistName());
- List<?> toMany2 = (List<?>) a2.readPropertyDirectly(Artist.ARTIST_EXHIBIT_ARRAY_PROPERTY);
- assertNotNull(toMany2);
- assertFalse(((ValueHolder) toMany2).isFault());
- assertEquals(3, toMany2.size());
-
- ArtistExhibit artistExhibit2 = (ArtistExhibit) toMany2.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit2.getPersistenceState());
- assertSame(a2, artistExhibit2.getToArtist());
- }
- });
- }
-
- public void testPrefetchToManyOnJoinTableJoinedPrefetch_ViaProperty() throws Exception {
- createTwoArtistsWithExhibitsDataSet();
-
- SelectQuery<Artist> q = new SelectQuery<Artist>(Artist.class);
- q.addPrefetch(Artist.ARTIST_EXHIBIT_ARRAY.joint());
- q.addOrdering(Artist.ARTIST_NAME.asc());
-
- final List<Artist> artists = context.select(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
-
- assertEquals(2, artists.size());
-
- Artist a1 = artists.get(0);
- assertEquals("artist2", a1.getArtistName());
- List<?> toMany = (List<?>) a1.readPropertyDirectly(Artist.ARTIST_EXHIBIT_ARRAY.getName());
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(2, toMany.size());
-
- ArtistExhibit artistExhibit = (ArtistExhibit) toMany.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit.getPersistenceState());
- assertSame(a1, artistExhibit.getToArtist());
-
- Artist a2 = artists.get(1);
- assertEquals("artist3", a2.getArtistName());
- List<?> toMany2 = (List<?>) a2.readPropertyDirectly(Artist.ARTIST_EXHIBIT_ARRAY.getName());
- assertNotNull(toMany2);
- assertFalse(((ValueHolder) toMany2).isFault());
- assertEquals(3, toMany2.size());
-
- ArtistExhibit artistExhibit2 = (ArtistExhibit) toMany2.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit2.getPersistenceState());
- assertSame(a2, artistExhibit2.getToArtist());
- }
- });
- }
-
- /**
- * Test that a to-many relationship is initialized when a target entity has
- * a compound PK only partially involved in relationship.
- */
- public void testPrefetchToManyOnJoinTableJoinedPrefetch() throws Exception {
- createTwoArtistsWithExhibitsDataSet();
-
- SelectQuery q = new SelectQuery(Artist.class);
- q.addPrefetch("artistExhibitArray").setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
- q.addOrdering(Artist.ARTIST_NAME_PROPERTY, SortOrder.ASCENDING);
-
- final List<Artist> artists = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
-
- assertEquals(2, artists.size());
-
- Artist a1 = artists.get(0);
- assertEquals("artist2", a1.getArtistName());
- List<?> toMany = (List<?>) a1.readPropertyDirectly("artistExhibitArray");
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- assertEquals(2, toMany.size());
-
- ArtistExhibit artistExhibit = (ArtistExhibit) toMany.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit.getPersistenceState());
- assertSame(a1, artistExhibit.getToArtist());
-
- Artist a2 = artists.get(1);
- assertEquals("artist3", a2.getArtistName());
- List<?> toMany2 = (List<?>) a2.readPropertyDirectly(Artist.ARTIST_EXHIBIT_ARRAY_PROPERTY);
- assertNotNull(toMany2);
- assertFalse(((ValueHolder) toMany2).isFault());
- assertEquals(3, toMany2.size());
-
- ArtistExhibit artistExhibit2 = (ArtistExhibit) toMany2.get(0);
- assertEquals(PersistenceState.COMMITTED, artistExhibit2.getPersistenceState());
- assertSame(a2, artistExhibit2.getToArtist());
- }
- });
- }
-
- /**
- * Test that a to-many relationship is initialized when there is no inverse
- * relationship
- */
- public void testPrefetch_ToManyNoReverse() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- ObjEntity paintingEntity = context.getEntityResolver().getObjEntity(Painting.class);
- ObjRelationship relationship = paintingEntity.getRelationship("toArtist");
- paintingEntity.removeRelationship("toArtist");
-
- try {
- SelectQuery q = new SelectQuery(Artist.class);
- q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
- final List<Artist> result = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertFalse(result.isEmpty());
- Artist a1 = result.get(0);
- List<?> toMany = (List<?>) a1.readPropertyDirectly("paintingArray");
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- }
- });
- } finally {
- paintingEntity.addRelationship(relationship);
- }
- }
-
- public void testPrefetch_ToManyNoReverseWithQualifier() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- ObjEntity paintingEntity = context.getEntityResolver().getObjEntity(Painting.class);
- ObjRelationship relationship = paintingEntity.getRelationship("toArtist");
- paintingEntity.removeRelationship("toArtist");
-
- try {
-
- SelectQuery q = new SelectQuery(Artist.class);
- q.setQualifier(ExpressionFactory.matchExp("artistName", "artist2"));
- q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);
-
- final List<Artist> result = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertFalse(result.isEmpty());
- Artist a1 = result.get(0);
- List<?> toMany = (List<?>) a1.readPropertyDirectly("paintingArray");
- assertNotNull(toMany);
- assertFalse(((ValueHolder) toMany).isFault());
- }
- });
-
- } finally {
- paintingEntity.addRelationship(relationship);
- }
- }
-
- public void testPrefetch_ToOne() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
-
- final List<Painting> result = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertFalse(result.isEmpty());
- Painting p1 = result.get(0);
-
- Object toOnePrefetch = p1.readNestedProperty("toArtist");
- assertNotNull(toOnePrefetch);
- assertTrue("Expected Artist, got: " + toOnePrefetch.getClass().getName(),
- toOnePrefetch instanceof Artist);
-
- Artist a1 = (Artist) toOnePrefetch;
- assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
- }
- });
- }
-
- public void testPrefetch_ToOne_DbPath() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
- q.andQualifier(ExpressionFactory.matchDbExp("toArtist.ARTIST_NAME", "artist2"));
-
- List<Painting> results = context.performQuery(q);
-
- assertEquals(1, results.size());
- }
-
- public void testPrefetch_ToOne_ObjPath() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
- q.andQualifier(ExpressionFactory.matchExp("toArtist.artistName", "artist2"));
-
- List<Painting> results = context.performQuery(q);
- assertEquals(1, results.size());
- }
-
- public void testPrefetch_ReflexiveRelationship() throws Exception {
- ArtGroup parent = (ArtGroup) context.newObject("ArtGroup");
- parent.setName("parent");
- ArtGroup child = (ArtGroup) context.newObject("ArtGroup");
- child.setName("child");
- child.setToParentGroup(parent);
- context.commitChanges();
-
- SelectQuery q = new SelectQuery("ArtGroup");
- q.setQualifier(ExpressionFactory.matchExp("name", "child"));
- q.addPrefetch("toParentGroup");
-
- final List<ArtGroup> results = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- ArtGroup fetchedChild = results.get(0);
- // The parent must be fully fetched, not just HOLLOW (a fault)
- assertEquals(PersistenceState.COMMITTED, fetchedChild.getToParentGroup().getPersistenceState());
- }
- });
- }
-
- public void testPrefetch_ToOneWithQualifierOverlappingPrefetchPath() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- Expression exp = ExpressionFactory.matchExp("toArtist.artistName", "artist3");
-
- SelectQuery q = new SelectQuery(Painting.class, exp);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
-
- final List<Painting> results = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- Painting painting = results.get(0);
-
- // The parent must be fully fetched, not just HOLLOW (a fault)
- assertEquals(PersistenceState.COMMITTED, painting.getToArtist().getPersistenceState());
- }
- });
- }
-
- public void testPrefetch_ToOneWith_OuterJoinFlattenedQualifier() throws Exception {
-
- tArtGroup.insert(1, "AG");
- tArtist.insert(11, "artist2");
- tArtist.insert(101, "artist3");
- tPainting.insert(6, "p_artist3", 101, 1000);
- tPainting.insert(7, "p_artist21", 11, 2000);
- tPainting.insert(8, "p_artist22", 11, 3000);
-
- // flattened join matches an object that is NOT the one we are looking
- // for
- tArtistGroup.insert(101, 1);
-
- // OUTER join part intentionally doesn't match anything
- Expression exp = new Property<String>("groupArray+.name").eq("XX").orExp(Artist.ARTIST_NAME.eq("artist2"));
-
- SelectQuery<Artist> q = new SelectQuery<Artist>(Artist.class, exp);
- q.addPrefetch(Artist.PAINTING_ARRAY.disjoint());
-
- final List<Artist> results = context.select(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- Artist a = results.get(0);
- assertEquals("artist2", a.getArtistName());
- assertEquals(2, a.getPaintingArray().size());
- }
- });
- }
-
- public void testPrefetch9() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- Expression artistExp = ExpressionFactory.matchExp("artistName", "artist3");
- SelectQuery artistQuery = new SelectQuery(Artist.class, artistExp);
- Artist artist1 = (Artist) context.performQuery(artistQuery).get(0);
-
- // find the painting not matching the artist (this is the case where
- // such prefetch
- // at least makes sense)
- Expression exp = ExpressionFactory.noMatchExp("toArtist", artist1);
-
- SelectQuery q = new SelectQuery(Painting.class, exp);
- q.addPrefetch("toArtist");
-
- final List<Painting> results = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- // see that artists are resolved...
-
- Painting px = results.get(0);
- Artist ax = (Artist) px.readProperty(Painting.TO_ARTIST_PROPERTY);
- assertEquals(PersistenceState.COMMITTED, ax.getPersistenceState());
- }
- });
- }
-
- public void testPrefetch_OneToOneWithQualifier() throws Exception {
- createArtistWithTwoPaintingsAndTwoInfosDataSet();
-
- Expression e = ExpressionFactory.likeExp("toArtist.artistName", "a%");
- SelectQuery q = new SelectQuery(Painting.class, e);
- q.addPrefetch(Painting.TO_PAINTING_INFO_PROPERTY);
- q.addOrdering(Painting.PAINTING_TITLE_PROPERTY, SortOrder.ASCENDING);
-
- final List<Painting> results = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(2, results.size());
-
- // testing non-null to-one target
- Painting p0 = results.get(0);
- Object o2 = p0.readPropertyDirectly(Painting.TO_PAINTING_INFO_PROPERTY);
- assertTrue(o2 instanceof PaintingInfo);
- PaintingInfo pi2 = (PaintingInfo) o2;
- assertEquals(PersistenceState.COMMITTED, pi2.getPersistenceState());
- assertEquals(Cayenne.intPKForObject(p0), Cayenne.intPKForObject(pi2));
-
- // testing null to-one target
- Painting p1 = results.get(1);
- assertNull(p1.readPropertyDirectly(Painting.TO_PAINTING_INFO_PROPERTY));
-
- // there was a bug marking an object as dirty when clearing the
- // relationships
- assertEquals(PersistenceState.COMMITTED, p1.getPersistenceState());
- }
- });
- }
-
- public void testPrefetchToMany_DateInQualifier() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- Expression e = ExpressionFactory.matchExp("dateOfBirth", new Date());
- SelectQuery q = new SelectQuery(Artist.class, e);
- q.addPrefetch("paintingArray");
-
- // prefetch with query using date in qualifier used to fail on SQL
- // Server
- // see CAY-119 for details
- context.performQuery(q);
- }
-
- public void testPrefetchingToOneNull() throws Exception {
-
- tPainting.insert(6, "p_Xty", null, 1000);
-
- SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
-
- final List<Painting> paintings = context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, paintings.size());
-
- Painting p2 = paintings.get(0);
- assertNull(p2.readProperty(Painting.TO_ARTIST_PROPERTY));
- }
- });
- }
-
- public void testPrefetchToOneSharedCache() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- final SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
- q.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
-
- context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- // per CAY-499 second run of a cached query with prefetches
- // (i.e. when the
- // result is served from cache) used to throw an exception...
-
- List<Painting> cachedResult = context.performQuery(q);
-
- assertFalse(cachedResult.isEmpty());
- Painting p1 = cachedResult.get(0);
-
- Object toOnePrefetch = p1.readNestedProperty("toArtist");
- assertNotNull(toOnePrefetch);
- assertTrue("Expected Artist, got: " + toOnePrefetch.getClass().getName(),
- toOnePrefetch instanceof Artist);
-
- Artist a1 = (Artist) toOnePrefetch;
- assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
-
- // and just in case - run one more time...
- context.performQuery(q);
- }
- });
- }
-
- public void testPrefetchToOneLocalCache() throws Exception {
- createTwoArtistsAndTwoPaintingsDataSet();
-
- final SelectQuery q = new SelectQuery(Painting.class);
- q.addPrefetch(Painting.TO_ARTIST_PROPERTY);
- q.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
-
- context.performQuery(q);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- // per CAY-499 second run of a cached query with prefetches
- // (i.e. when the
- // result is served from cache) used to throw an exception...
-
- List<Painting> cachedResult = context.performQuery(q);
-
- assertFalse(cachedResult.isEmpty());
- Painting p1 = cachedResult.get(0);
-
- Object toOnePrefetch = p1.readNestedProperty("toArtist");
- assertNotNull(toOnePrefetch);
- assertTrue("Expected Artist, got: " + toOnePrefetch.getClass().getName(),
- toOnePrefetch instanceof Artist);
-
- Artist a1 = (Artist) toOnePrefetch;
- assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
-
- // and just in case - run one more time...
- context.performQuery(q);
- }
- });
- }
-
- public void testPrefetchToOneWithBackRelationship() throws Exception {
- createArtistWithTwoPaintingsAndTwoInfosDataSet();
-
- SelectQuery<Painting> query = new SelectQuery<Painting>(Painting.class);
- query.andQualifier(Painting.PAINTING_TITLE.eq("p_artist2"));
- query.addPrefetch(Painting.TO_PAINTING_INFO.disjoint());
- query.addPrefetch(Painting.TO_PAINTING_INFO.dot(PaintingInfo.PAINTING).disjoint());
- final List<Painting> results = context.select(query);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- Painting p0 = results.get(0);
- PaintingInfo pi0 = (PaintingInfo) p0.readPropertyDirectly(Painting.TO_PAINTING_INFO.getName());
- assertNotNull(pi0);
- assertNotNull(pi0.readPropertyDirectly(PaintingInfo.PAINTING.getName()));
- }
- });
- }
-
- public void testPrefetchPaintingOverToOneAndToMany() throws Exception {
- createArtistWithTwoPaintingsAndTwoInfosDataSet();
-
- SelectQuery<Painting> query = new SelectQuery<Painting>(Painting.class);
- query.andQualifier(Painting.PAINTING_TITLE.eq("p_artist2"));
- query.addPrefetch(Painting.TO_ARTIST.disjoint());
- query.addPrefetch(Painting.TO_ARTIST.dot(Artist.PAINTING_ARRAY).disjoint());
- final List<Painting> results = context.select(query);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- Painting p0 = results.get(0);
- Artist a0 = (Artist) p0.readPropertyDirectly(Painting.TO_ARTIST.getName());
- assertNotNull(a0);
- List<?> paintings = (List<?>) a0.readPropertyDirectly(Artist.PAINTING_ARRAY.getName());
- assertEquals(2, paintings.size());
- }
- });
- }
-
- public void testPrefetchToOneWithBackRelationship_Joint() throws Exception {
- createArtistWithTwoPaintingsAndTwoInfosDataSet();
-
- SelectQuery<Painting> query = new SelectQuery<Painting>(Painting.class);
- query.andQualifier(Painting.PAINTING_TITLE.eq("p_artist2"));
- query.addPrefetch(Painting.TO_PAINTING_INFO.joint());
- query.addPrefetch(Painting.TO_PAINTING_INFO.dot(PaintingInfo.PAINTING).joint());
- final List<Painting> results = context.select(query);
-
- queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
- public void execute() {
- assertEquals(1, results.size());
-
- Painting p0 = results.get(0);
- PaintingInfo pi0 = (PaintingInfo) p0.readPropertyDirectly(Painting.TO_PAINTING_INFO.getName());
- assertNotNull(pi0);
- assertNotNull(pi0.readPropertyDirectly(PaintingInfo.PAINTING.getName()));
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/e42c376c/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextProcedureQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextProcedureQueryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextProcedureQueryIT.java
new file mode 100644
index 0000000..2937935
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextProcedureQueryIT.java
@@ -0,0 +1,429 @@
+/*****************************************************************
+ * 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.DataRow;
+import org.apache.cayenne.access.jdbc.ColumnDescriptor;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.query.CapsStrategy;
+import org.apache.cayenne.query.ProcedureQuery;
+import org.apache.cayenne.query.SelectQuery;
+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.tx.BaseTransaction;
+import org.apache.cayenne.tx.ExternalTransaction;
+import org.apache.cayenne.unit.UnitDbAdapter;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.math.BigDecimal;
+import java.sql.Types;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DataContextProcedureQueryIT extends ServerCase {
+
+ public static final String UPDATE_STORED_PROCEDURE = "cayenne_tst_upd_proc";
+ public static final String UPDATE_STORED_PROCEDURE_NOPARAM = "cayenne_tst_upd_proc2";
+ public static final String SELECT_STORED_PROCEDURE = "cayenne_tst_select_proc";
+ public static final String OUT_STORED_PROCEDURE = "cayenne_tst_out_proc";
+
+ @Inject
+ private DataContext context;
+
+ @Inject
+ private UnitDbAdapter accessStackAdapter;
+
+ @Inject
+ protected DBHelper dbHelper;
+
+ @Inject
+ private JdbcEventLogger jdbcEventLogger;
+
+ @Override
+ protected void setUpAfterInjection() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ dbHelper.deleteAll("PAINTING_INFO");
+ dbHelper.deleteAll("PAINTING");
+ dbHelper.deleteAll("ARTIST_EXHIBIT");
+ dbHelper.deleteAll("ARTIST_GROUP");
+ dbHelper.deleteAll("ARTIST");
+ }
+
+ public void testUpdate() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ ProcedureQuery q = new ProcedureQuery(UPDATE_STORED_PROCEDURE);
+ q.addParameter("paintingPrice", new Integer(3000));
+
+ // since stored procedure commits its stuff, we must use an explicit
+ // non-committing transaction
+
+ BaseTransaction t = new ExternalTransaction(jdbcEventLogger);
+ BaseTransaction.bindThreadTransaction(t);
+
+ try {
+ context.performGenericQuery(q);
+ } finally {
+ BaseTransaction.bindThreadTransaction(null);
+ t.commit();
+ }
+
+ // check that price have doubled
+ SelectQuery select = new SelectQuery(Artist.class);
+ select.addPrefetch("paintingArray");
+
+ List<?> artists = context.performQuery(select);
+ assertEquals(1, artists.size());
+
+ Artist a = (Artist) artists.get(0);
+ Painting p = a.getPaintingArray().get(0);
+ assertEquals(2000, p.getEstimatedPrice().intValue());
+ }
+
+ public void testUpdateNoParam() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ ProcedureQuery q = new ProcedureQuery(UPDATE_STORED_PROCEDURE_NOPARAM);
+
+ // since stored procedure commits its stuff, we must use an explicit
+ // non-committing transaction
+
+ BaseTransaction t = new ExternalTransaction(jdbcEventLogger);
+ BaseTransaction.bindThreadTransaction(t);
+
+ try {
+ context.performGenericQuery(q);
+ } finally {
+ BaseTransaction.bindThreadTransaction(null);
+ t.commit();
+ }
+
+ // check that price have doubled
+ SelectQuery select = new SelectQuery(Artist.class);
+ select.addPrefetch("paintingArray");
+
+ List<?> artists = context.performQuery(select);
+ assertEquals(1, artists.size());
+
+ Artist a = (Artist) artists.get(0);
+ Painting p = a.getPaintingArray().get(0);
+ assertEquals(2000, p.getEstimatedPrice().intValue());
+ }
+
+ public void testSelect1() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+ List<?> artists = runProcedureSelect(q);
+
+ // check the results
+ assertNotNull("Null result from StoredProcedure.", artists);
+ assertEquals(1, artists.size());
+ DataRow artistRow = (DataRow) artists.get(0);
+ Artist a = context.objectFromDataRow(Artist.class, uppercaseConverter(artistRow));
+ Painting p = a.getPaintingArray().get(0);
+
+ // invalidate painting, it may have been updated in the proc
+ context.invalidateObjects(p);
+ assertEquals(2000, p.getEstimatedPrice().intValue());
+ }
+
+ public void testSelect2() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+
+ List<?> artists = runProcedureSelect(q);
+
+ // check the results
+ assertNotNull("Null result from StoredProcedure.", artists);
+ assertEquals(1, artists.size());
+ DataRow artistRow = (DataRow) artists.get(0);
+ Artist a = context.objectFromDataRow(Artist.class, uppercaseConverter(artistRow));
+ Painting p = a.getPaintingArray().get(0);
+
+ // invalidate painting, it may have been updated in the proc
+ context.invalidateObjects(p);
+ assertEquals(2000, p.getEstimatedPrice().intValue());
+ }
+
+ public void testSelect3() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ // test ProcedureQuery with Procedure as root
+ Procedure proc = context.getEntityResolver().getProcedure(SELECT_STORED_PROCEDURE);
+ ProcedureQuery q = new ProcedureQuery(proc);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+
+ List<?> artists = runProcedureSelect(q);
+
+ // check the results
+ assertNotNull("Null result from StoredProcedure.", artists);
+ assertEquals(1, artists.size());
+ DataRow artistRow = (DataRow) artists.get(0);
+ Artist a = context.objectFromDataRow(Artist.class, uppercaseConverter(artistRow));
+ Painting p = a.getPaintingArray().get(0);
+
+ // invalidate painting, it may have been updated in the proc
+ context.invalidateObjects(p);
+ assertEquals(2000, p.getEstimatedPrice().intValue());
+ }
+
+ public void testFetchLimit() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+ createArtist(2000.0);
+ createArtist(3000.0);
+
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+ q.setFetchLimit(2);
+ List<?> artists = runProcedureSelect(q);
+
+ assertEquals(2, artists.size());
+ }
+
+ public void testFetchOffset() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+ createArtist(2000.0);
+ createArtist(3000.0);
+
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+ q.setFetchOffset(2);
+ List<?> artists = runProcedureSelect(q);
+
+ assertEquals(1, artists.size());
+ }
+
+ public void testColumnNameCapitalization() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+
+ q.setColumnNamesCapitalization(CapsStrategy.LOWER);
+ q.addParameter("aName", "An Artist");
+ List<DataRow> artists = runProcedureSelect(q);
+
+ ProcedureQuery q1 = new ProcedureQuery(SELECT_STORED_PROCEDURE);
+
+ q1.setColumnNamesCapitalization(CapsStrategy.UPPER);
+ q1.addParameter("aName", "An Artist");
+ List<DataRow> artists1 = runProcedureSelect(q1);
+
+ assertTrue(artists.get(0).containsKey("date_of_birth"));
+ assertFalse(artists.get(0).containsKey("DATE_OF_BIRTH"));
+
+ assertFalse(artists1.get(0).containsKey("date_of_birth"));
+ assertTrue(artists1.get(0).containsKey("DATE_OF_BIRTH"));
+
+ }
+
+ public void testOutParams() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ ProcedureQuery q = new ProcedureQuery(OUT_STORED_PROCEDURE);
+ q.addParameter("in_param", new Integer(20));
+
+ List<?> rows = runProcedureSelect(q);
+
+ assertEquals(1, rows.size());
+ Object row = rows.get(0);
+ assertNotNull(row);
+ assertTrue("Unexpected row class: " + row.getClass().getName(), row instanceof Map<?, ?>);
+ Map<?, ?> outParams = (Map<?, ?>) row;
+ Number price = (Number) outParams.get("out_param");
+ assertNotNull("Null result... row content: " + row, price);
+ assertEquals(40, price.intValue());
+ }
+
+ public void testSelectDataObject() throws Exception {
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ if (!accessStackAdapter.canMakeObjectsOutOfProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1101.01);
+
+ ProcedureQuery q = new ProcedureQuery(SELECT_STORED_PROCEDURE, Artist.class);
+ q.addParameter("aName", "An Artist");
+
+ List<?> artists = runProcedureSelect(q);
+
+ // check the results
+ assertNotNull("Null result from StoredProcedure.", artists);
+ assertEquals(1, artists.size());
+ Artist a = (Artist) artists.get(0);
+ Painting p = a.getPaintingArray().get(0);
+
+ // invalidate painting, it may have been updated in the proc
+ context.invalidateObjects(p);
+ assertEquals(1101.01, p.getEstimatedPrice().doubleValue(), 0.02);
+ }
+
+ public void testSelectWithRowDescriptor() throws Exception {
+
+ if (!accessStackAdapter.supportsStoredProcedures()) {
+ return;
+ }
+
+ // create an artist with painting in the database
+ createArtist(1000.0);
+
+ // test ProcedureQuery with Procedure as root
+ Procedure proc = context.getEntityResolver().getProcedure(SELECT_STORED_PROCEDURE);
+ ProcedureQuery q = new ProcedureQuery(proc);
+ q.setFetchingDataRows(true);
+ q.addParameter("aName", "An Artist");
+ q.addParameter("paintingPrice", new Integer(3000));
+
+ // TESTING THIS ***
+ // A.ARTIST_ID, A.DATE_OF_BIRTH, A.ARTIST_NAME
+ ColumnDescriptor[] columns = new ColumnDescriptor[3];
+
+ // read ID as Long, and everything else as default types
+ columns[0] = new ColumnDescriptor("ARTIST_ID", Types.BIGINT);
+ columns[1] = new ColumnDescriptor("ARTIST_NAME", Types.CHAR);
+ columns[2] = new ColumnDescriptor("DATE_OF_BIRTH", Types.DATE);
+ q.addResultDescriptor(columns);
+
+ List<?> rows = runProcedureSelect(q);
+
+ // check the results
+ assertNotNull("Null result from StoredProcedure.", rows);
+ assertEquals(1, rows.size());
+ DataRow artistRow = (DataRow) rows.get(0);
+
+ assertEquals(3, artistRow.size());
+
+ artistRow = uppercaseConverter(artistRow);
+
+ Object id = artistRow.get("ARTIST_ID");
+ assertNotNull(id);
+ assertTrue("Expected Long, got: " + id.getClass().getName(), id instanceof Long);
+ }
+
+ protected List<DataRow> runProcedureSelect(ProcedureQuery q) throws Exception {
+ // Sybase blows whenever a transaction wraps a SP, so turn off
+ // transactions
+
+ // TODO: it is quite the opposite with PostgreSQL. If an SP returns an
+ // open refcursor, it actually expects a TX in progress, so while we
+ // don't have refcursor unit tests, this is something to keep in mind
+ // e.g.
+ // http://stackoverflow.com/questions/16921942/porting-apache-cayenne-from-oracle-to-postgresql
+
+ BaseTransaction t = new ExternalTransaction(jdbcEventLogger);
+ BaseTransaction.bindThreadTransaction(t);
+
+ try {
+ return context.performQuery(q);
+ } finally {
+ BaseTransaction.bindThreadTransaction(null);
+ t.commit();
+ }
+ }
+
+ protected void createArtist(double paintingPrice) {
+ Artist a = context.newObject(Artist.class);
+ a.setArtistName("An Artist");
+
+ Painting p = context.newObject(Painting.class);
+ p.setPaintingTitle("A Painting");
+ // converting double to string prevents rounding weirdness...
+ p.setEstimatedPrice(new BigDecimal("" + paintingPrice));
+ a.addToPaintingArray(p);
+
+ context.commitChanges();
+ }
+
+ /**
+ * An ugly hack - converting row keys to uppercase ... Tracked via CAY-148.
+ */
+ protected DataRow uppercaseConverter(DataRow row) {
+ DataRow converted = new DataRow(row.size());
+
+ for (Entry<String, Object> entry : row.entrySet()) {
+ converted.put(entry.getKey().toString().toUpperCase(), entry.getValue());
+ }
+
+ return converted;
+ }
+}