From ff9449f78c7507ead37bb86f71bf4ba03b3d9a1f Mon Sep 17 00:00:00 2001 From: John Huss Date: Mon, 3 Oct 2022 11:23:05 -0500 Subject: [PATCH 1/2] Fix NPE in ConcurrentLinkedHashMap --- .../util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java | 1 + 1 file changed, 1 insertion(+) diff --git a/cayenne/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java b/cayenne/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java index e1d98563fd..772ced0e57 100644 --- a/cayenne/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java +++ b/cayenne/src/main/java/org/apache/cayenne/util/concurrentlinkedhashmap/ConcurrentLinkedHashMap.java @@ -788,6 +788,7 @@ else if (onlyIfAbsent) { @Override public V remove(Object key) { + if (key == null) return null; // this class does allow null to be used as a key or value (returning here prevents an NPE). final Node node = data.remove(key); if (node == null) { return null; From a35c7d5885b8396af44b0002174cef9335268812 Mon Sep 17 00:00:00 2001 From: John Huss Date: Thu, 17 Oct 2024 15:38:17 -0500 Subject: [PATCH 2/2] disjoint and disjointById prefetches over 2 hops with both hops prefetched returns incorrect data --- .../DataContextPrefetchMultistepIT.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepIT.java index 7bc9eab7b9..ca3639f263 100644 --- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepIT.java +++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextPrefetchMultistepIT.java @@ -28,6 +28,7 @@ import org.apache.cayenne.query.ObjectSelect; 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.ArtistExhibit; import org.apache.cayenne.testdo.testmap.Exhibit; import org.apache.cayenne.testdo.testmap.Gallery; @@ -286,4 +287,66 @@ public void testToManyToOne_EmptyToMany_NoRootQualifier() throws Exception { assertFalse(((ValueHolder) exhibits).isFault()); assertEquals(0, exhibits.size()); } + + private Gallery createArtistWithPaintingInGallery() { + Artist artist = context.newObject(Artist.class); + artist.setArtistName("Picasso"); + + Painting painting = context.newObject(Painting.class); + painting.setPaintingTitle("Guernica"); + artist.addToPaintingArray(painting); + + Gallery gallery = context.newObject(Gallery.class); + gallery.setGalleryName("MOMA"); + painting.setToGallery(gallery); + + context.commitChanges(); + return gallery; + } + + @Test + public void testPrefetchAcross2RelationshipsKeepingBoth_Joint() { + Gallery gallery = createArtistWithPaintingInGallery(); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + + // Prefetch the artist through the two relationships + ObjectSelect.query(Gallery.class) + .prefetch(Gallery.PAINTING_ARRAY.joint()) + .prefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).joint()) + .select(context); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + } + + @Test + public void testPrefetchAcross2RelationshipsKeepingBoth_Disjoint() { + Gallery gallery = createArtistWithPaintingInGallery(); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + + // Prefetch the artist through the two relationships + ObjectSelect.query(Gallery.class) + .prefetch(Gallery.PAINTING_ARRAY.joint()) + .prefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).disjoint()) + .select(context); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + } + + @Test + public void testPrefetchAcross2RelationshipsKeepingBoth_DisjointById() { + Gallery gallery = createArtistWithPaintingInGallery(); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + + // Prefetch the artist through the two relationships + ObjectSelect.query(Gallery.class) + .prefetch(Gallery.PAINTING_ARRAY.joint()) + .prefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).disjointById()) + .select(context); + + assertNotNull(gallery.getPaintingArray().get(0).getToArtist()); + } + }