This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new aee5997  CAY-2092 Exception for query that uses pagination and sorting 
on to-many
aee5997 is described below

commit aee5997f6afbdb91d734915739b71d2ac88ef165
Author: Nikita Timofeev <stari...@gmail.com>
AuthorDate: Thu Apr 22 11:53:56 2021 +0300

    CAY-2092 Exception for query that uses pagination and sorting on to-many
---
 RELEASE-NOTES.txt                                  |  1 +
 .../cayenne/access/IncrementalFaultList.java       | 55 ++++++++++++----------
 .../apache/cayenne/query/ObjectSelect_RunIT.java   | 13 +++++
 3 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 5b9ba34..bfd7592 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -15,6 +15,7 @@ Changes/New Features:
 
 Bug Fixes:
 
+CAY-2092 Exception for query that uses pagination and sorting on to-many
 CAY-2702 Modeler: Callbacks table has too small default width
 CAY-2703 Modeler: incorrect active tab style on the MacOS version
 CAY-2705 Performance of callback annotation processing
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
index 43f64ba..c4648d3 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
@@ -289,39 +289,42 @@ public class IncrementalFaultList<E> implements List<E>, 
Serializable {
         * @since 3.0
         */
        void checkPageResultConsistency(List<?> objects, List<?> ids) {
+               if (objects.size() == ids.size()) {
+                       return;
+               } else if (objects.size() > ids.size()) {
+                       throw new CayenneRuntimeException("Expected %d objects, 
retrieved %d", ids.size(), objects.size());
+               }
 
-               if (objects.size() < ids.size()) {
-                       // find missing ids
-                       StringBuilder buffer = new StringBuilder();
-                       buffer.append("Some ObjectIds are missing from the 
database. ");
-                       buffer.append("Expected ").append(ids.size()).append(", 
fetched ").append(objects.size());
-
-                       boolean first = true;
-                       for (Object id : ids) {
-                               boolean found = false;
-
-                               for (Object object : objects) {
-
-                                       if (getHelper().replacesObject(object, 
id)) {
-                                               found = true;
-                                               break;
-                                       }
+               // We have less objects then ids
+               // check that we are really missing some ids and throw an 
exception in that case
+               StringBuilder buffer = null;
+               boolean first = true;
+               for (Object id : ids) {
+                       boolean found = false;
+                       for (Object object : objects) {
+                               if (getHelper().replacesObject(object, id)) {
+                                       found = true;
+                                       break;
                                }
+                       }
 
-                               if (!found) {
-                                       if (first) {
-                                               first = false;
-                                       } else {
-                                               buffer.append(", ");
-                                       }
-
-                                       buffer.append(id.toString());
+                       if (!found) {
+                               if(buffer == null) {
+                                       buffer = new StringBuilder();
                                }
+                               if (first) {
+                                       first = false;
+                               } else {
+                                       buffer.append(", ");
+                               }
+                               buffer.append(id.toString());
                        }
+               }
 
+               // we have some objects missing, throw
+               if(buffer != null) {
+                       buffer.insert(0, "Some ObjectIds are missing from the 
database. Expected " + ids.size() + ", fetched " + objects.size());
                        throw new CayenneRuntimeException(buffer.toString());
-               } else if (objects.size() > ids.size()) {
-                       throw new CayenneRuntimeException("Expected %d objects, 
retrieved %d", ids.size(), objects.size());
                }
        }
 
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
index e9b05e3..025428f 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
 import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -223,4 +224,16 @@ public class ObjectSelect_RunIT extends ServerCase {
 
                assertEquals(1, artists.size());
        }
+
+       @Test
+       public void test_CAY_2092() {
+               List<Artist> artists = ObjectSelect.query(Artist.class)
+                               
.orderBy(Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).asc())
+                               .pageSize(5)
+                               .select(context);
+               // just read everything to trigger page resolving
+               for (Artist artist : artists) {
+                       assertNotNull(artist);
+               }
+       }
 }

Reply via email to