From commits-return-15299-apmail-cayenne-commits-archive=cayenne.apache.org@cayenne.apache.org Mon Mar 17 23:04:44 2014 Return-Path: X-Original-To: apmail-cayenne-commits-archive@www.apache.org Delivered-To: apmail-cayenne-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A4C2510041 for ; Mon, 17 Mar 2014 23:04:44 +0000 (UTC) Received: (qmail 37923 invoked by uid 500); 17 Mar 2014 23:04:43 -0000 Delivered-To: apmail-cayenne-commits-archive@cayenne.apache.org Received: (qmail 37900 invoked by uid 500); 17 Mar 2014 23:04:43 -0000 Mailing-List: contact commits-help@cayenne.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cayenne.apache.org Delivered-To: mailing list commits@cayenne.apache.org Received: (qmail 37890 invoked by uid 99); 17 Mar 2014 23:04:42 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 17 Mar 2014 23:04:42 +0000 Date: Mon, 17 Mar 2014 23:04:42 +0000 (UTC) From: =?utf-8?Q?Mika=C3=ABl_Cluseau_=28JIRA=29?= To: commits@cayenne.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Comment Edited] (CAY-1905) Multi-step prefetching NPE : 1..N..1 with absent N and root with no qualifier MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/CAY-1905?page=3Dcom.atlassian.j= ira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D139385= 27#comment-13938527 ]=20 Mika=C3=ABl Cluseau edited comment on CAY-1905 at 3/17/14 11:03 PM: --------------------------------------------------------------- The code that handles the prefetches: {code:java} for (String prefetch : allPrefetches) { =09LOG.info("Adding prefetch: " + prefetch); =09PrefetchTreeNode prefetchTreeNode =3D query =09=09=09.addPrefetch(prefetch); =09if (canUseJoinPrefetch(entity, prefetch)) { =09=09prefetchTreeNode.setSemantics(JOINT_PREFETCH_SEMANTICS); =09} } {code} canUseJoinPrefetch returns false if is finds a toMany or a not mandatory re= lationship for the given path. The resulting log: {code} INFO - Adding prefetch: address1 INFO - Adding prefetch: address1.way INFO - Adding prefetch: address1.city INFO - Adding prefetch: person INFO - --- transaction started. INFO - SELECT t0.* FROM app.file t0 JOIN app.person t1 ON (t0.person_2_id = =3D t1.id) WHERE t1.name_2 ILIKE ? [bind: 1->name_2:'%xx%'] INFO - =3D=3D=3D returned 4 rows. - took 6 ms. INFO - +++ transaction committed. INFO - --- transaction started. INFO - SELECT t0.*, t1.*, t2.* FROM app.file t0 LEFT JOIN app.address t1 ON= (t0.address_1_id =3D t1.id) LEFT JOIN app.person t2 ON (t0.person_id =3D t= 2.id) WHERE (t0.id IN (?, [...], ?)) [bind: 1->id:123, [...], 56->id:456] -= prepared in 7 ms. INFO - =3D=3D=3D returned 56 rows. - took 29 ms. INFO - SELECT DISTINCT t0.* FROM global.way t0 JOIN app.address t1 ON (t0.w= ay_code =3D t1.way_code) JOIN app.file t2 ON (t1.id =3D t2.address_1_id) WH= ERE t2.id IN (?, [...], ?) [bind: 1->id:123, [...], 56->id:456] INFO - =3D=3D=3D returned 38 rows. - took 16 ms. INFO - SELECT DISTINCT t0.* FROM global.city t0 JOIN app.address t1 ON (t0.= city_code =3D t1.city_code) JOIN app.file t2 ON (t1.id =3D t2.address_1_id)= WHERE t2.id IN (?, [...], ?) [bind: 1->id:123, [...], 56->id:456] INFO - =3D=3D=3D returned 1 row. - took 4 ms. INFO - +++ transaction committed. {code} The stack trace: {code} org.apache.cayenne.access.ResultScanParentAttachmentStrategy.indexParents(R= esultScanParentAttachmentStrategy.java:113) org.apache.cayenne.access.ResultScanParentAttachmentStrategy.linkToParent(R= esultScanParentAttachmentStrategy.java:72) org.apache.cayenne.access.HierarchicalObjectResolverNode.objectsFromDataRow= s(HierarchicalObjectResolverNode.java:70) org.apache.cayenne.access.HierarchicalObjectResolver$DisjointProcessor.star= tDisjointPrefetch(HierarchicalObjectResolver.java:121) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:20= 6) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:22= 1) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:22= 1) org.apache.cayenne.access.HierarchicalObjectResolver.resolveObjectTree(Hier= archicalObjectResolver.java:96) org.apache.cayenne.access.HierarchicalObjectResolver.synchronizedRootResult= NodeFromDataRows(HierarchicalObjectResolver.java:78) org.apache.cayenne.access.DataDomainQueryAction$ObjectConversionStrategy.to= ResultsTree(DataDomainQueryAction.java:605) org.apache.cayenne.access.DataDomainQueryAction$SingleObjectConversionStrat= egy.convert(DataDomainQueryAction.java:643) org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConversion(D= ataDomainQueryAction.java:468) org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQueryActi= on.java:129) org.apache.cayenne.access.DataDomain.onQueryNoFilters(DataDomain.java:610) org.apache.cayenne.access.DataDomain$DataDomainQueryFilterChain.onQuery(Dat= aDomain.java:847) org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:602) org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQuer= yAction.java:350) org.apache.cayenne.util.ObjectContextQueryAction.executePostCache(ObjectCon= textQueryAction.java:106) org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectContextQuery= Action.java:93) org.apache.cayenne.access.DataContext.onQuery(DataContext.java:968) org.apache.cayenne.access.DataContext.performQuery(DataContext.java:957) {code} was (Author: mcluseau): The code that handles the prefetches: {code:java} for (String prefetch : allPrefetches) { =09LOG.info("Adding prefetch: " + prefetch); =09PrefetchTreeNode prefetchTreeNode =3D query =09=09=09.addPrefetch(prefetch); =09if (canUseJoinPrefetch(entity, prefetch)) { =09=09prefetchTreeNode.setSemantics(JOINT_PREFETCH_SEMANTICS); =09} } {code} canUsePrefetch returns false if is finds a toMany or a not mandatory relati= onship for the given path. The resulting log: {code} INFO - Adding prefetch: address1 INFO - Adding prefetch: address1.way INFO - Adding prefetch: address1.city INFO - Adding prefetch: person INFO - --- transaction started. INFO - SELECT t0.* FROM app.file t0 JOIN app.person t1 ON (t0.person_2_id = =3D t1.id) WHERE t1.name_2 ILIKE ? [bind: 1->name_2:'%xx%'] INFO - =3D=3D=3D returned 4 rows. - took 6 ms. INFO - +++ transaction committed. INFO - --- transaction started. INFO - SELECT t0.*, t1.*, t2.* FROM app.file t0 LEFT JOIN app.address t1 ON= (t0.address_1_id =3D t1.id) LEFT JOIN app.person t2 ON (t0.person_id =3D t= 2.id) WHERE (t0.id IN (?, [...], ?)) [bind: 1->id:123, [...], 56->id:456] -= prepared in 7 ms. INFO - =3D=3D=3D returned 56 rows. - took 29 ms. INFO - SELECT DISTINCT t0.* FROM global.way t0 JOIN app.address t1 ON (t0.w= ay_code =3D t1.way_code) JOIN app.file t2 ON (t1.id =3D t2.address_1_id) WH= ERE t2.id IN (?, [...], ?) [bind: 1->id:123, [...], 56->id:456] INFO - =3D=3D=3D returned 38 rows. - took 16 ms. INFO - SELECT DISTINCT t0.* FROM global.city t0 JOIN app.address t1 ON (t0.= city_code =3D t1.city_code) JOIN app.file t2 ON (t1.id =3D t2.address_1_id)= WHERE t2.id IN (?, [...], ?) [bind: 1->id:123, [...], 56->id:456] INFO - =3D=3D=3D returned 1 row. - took 4 ms. INFO - +++ transaction committed. {code} The stack trace: {code} org.apache.cayenne.access.ResultScanParentAttachmentStrategy.indexParents(R= esultScanParentAttachmentStrategy.java:113) org.apache.cayenne.access.ResultScanParentAttachmentStrategy.linkToParent(R= esultScanParentAttachmentStrategy.java:72) org.apache.cayenne.access.HierarchicalObjectResolverNode.objectsFromDataRow= s(HierarchicalObjectResolverNode.java:70) org.apache.cayenne.access.HierarchicalObjectResolver$DisjointProcessor.star= tDisjointPrefetch(HierarchicalObjectResolver.java:121) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:20= 6) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:22= 1) org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode.java:22= 1) org.apache.cayenne.access.HierarchicalObjectResolver.resolveObjectTree(Hier= archicalObjectResolver.java:96) org.apache.cayenne.access.HierarchicalObjectResolver.synchronizedRootResult= NodeFromDataRows(HierarchicalObjectResolver.java:78) org.apache.cayenne.access.DataDomainQueryAction$ObjectConversionStrategy.to= ResultsTree(DataDomainQueryAction.java:605) org.apache.cayenne.access.DataDomainQueryAction$SingleObjectConversionStrat= egy.convert(DataDomainQueryAction.java:643) org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConversion(D= ataDomainQueryAction.java:468) org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQueryActi= on.java:129) org.apache.cayenne.access.DataDomain.onQueryNoFilters(DataDomain.java:610) org.apache.cayenne.access.DataDomain$DataDomainQueryFilterChain.onQuery(Dat= aDomain.java:847) org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:602) org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQuer= yAction.java:350) org.apache.cayenne.util.ObjectContextQueryAction.executePostCache(ObjectCon= textQueryAction.java:106) org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectContextQuery= Action.java:93) org.apache.cayenne.access.DataContext.onQuery(DataContext.java:968) org.apache.cayenne.access.DataContext.performQuery(DataContext.java:957) {code} > Multi-step prefetching NPE : 1..N..1 with absent N and root with no quali= fier > -------------------------------------------------------------------------= ---- > > Key: CAY-1905 > URL: https://issues.apache.org/jira/browse/CAY-1905 > Project: Cayenne > Issue Type: Bug > Affects Versions: 3.1RC1, 3.2M1 > Reporter: Andrus Adamchik > Assignee: Andrus Adamchik > Fix For: 3.1 (final), 3.2.M2 > > > When all of these conditions are true in a query with prefetching, the qu= ery fails with an NPE: > 1. Disjoint Prefetching is done as 1..N..1 (actually cardinality may not = a q requirement) > 2. Intermediate entity has no rows. Root entity and final entity do. > 3. Root query has no qualifier. > SelectQuery q =3D SelectQuery.query(Gallery.class); > q.addPrefetch(Gallery.PAINTING_ARRAY.disjoint()); > q.addPrefetch(Gallery.PAINTING_ARRAY.dot(Painting.TO_ARTIST).disj= oint()); > List galleries =3D context.select(q); > INFO: SELECT t0.GALLERY_NAME, t0.GALLERY_ID FROM GALLERY t0 > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= SelectCount > INFO: =3D=3D=3D returned 3 rows. - took 7 ms. > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= Query > INFO: SELECT t0.ESTIMATED_PRICE, t0.PAINTING_DESCRIPTION, t0.PAINTING_TIT= LE, t0.ARTIST_ID, t0.GALLERY_ID, t0.PAINTING_ID, t1.GALLERY_ID FROM PAINTIN= G t0 JOIN GALLERY t1 ON (t0.GALLERY_ID =3D t1.GALLERY_ID) > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= SelectCount > INFO: =3D=3D=3D returned 0 rows. - took 6 ms. > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= Query > INFO: SELECT t0.ARTIST_NAME, t0.DATE_OF_BIRTH, t0.ARTIST_ID FROM ARTIST t= 0 > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= SelectCount > INFO: =3D=3D=3D returned 2 rows. - took 2 ms. > Mar 11, 2014 2:59:01 PM org.apache.cayenne.log.CommonsJdbcEventLogger log= CommitTransaction > INFO: +++ transaction committed. > java.lang.NullPointerException > =09at org.apache.cayenne.access.ResultScanParentAttachmentStrategy.indexP= arents(ResultScanParentAttachmentStrategy.java:104) > =09at org.apache.cayenne.access.ResultScanParentAttachmentStrategy.linkTo= Parent(ResultScanParentAttachmentStrategy.java:72) > =09at org.apache.cayenne.access.HierarchicalObjectResolverNode.objectsFro= mDataRows(HierarchicalObjectResolverNode.java:70) > =09at org.apache.cayenne.access.HierarchicalObjectResolver$DisjointProces= sor.startDisjointPrefetch(HierarchicalObjectResolver.java:121) > =09at org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode= .java:206) > =09at org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode= .java:221) > =09at org.apache.cayenne.query.PrefetchTreeNode.traverse(PrefetchTreeNode= .java:221) > =09at org.apache.cayenne.access.HierarchicalObjectResolver.resolveObjectT= ree(HierarchicalObjectResolver.java:96) > =09at org.apache.cayenne.access.HierarchicalObjectResolver.synchronizedRo= otResultNodeFromDataRows(HierarchicalObjectResolver.java:78) > =09at org.apache.cayenne.access.DataDomainQueryAction$ObjectConversionStr= ategy.toResultsTree(DataDomainQueryAction.java:605) > =09at org.apache.cayenne.access.DataDomainQueryAction$SingleObjectConvers= ionStrategy.convert(DataDomainQueryAction.java:643) > =09at org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConv= ersion(DataDomainQueryAction.java:468) > =09at org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQ= ueryAction.java:129) > =09at org.apache.cayenne.access.UnitTestDomainQueryAction.execute(UnitTes= tDomainQueryAction.java:47) > =09at org.apache.cayenne.access.UnitTestDomain.onQueryNoFilters(UnitTestD= omain.java:63) > =09at org.apache.cayenne.access.DataDomain$DataDomainQueryFilterChain.onQ= uery(DataDomain.java:847) > =09at org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:602) > =09at org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectCon= textQueryAction.java:350) > =09at org.apache.cayenne.util.ObjectContextQueryAction.executePostCache(O= bjectContextQueryAction.java:106) > =09at org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectCont= extQueryAction.java:93) > =09at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:962) > =09at org.apache.cayenne.access.DataContext.performQuery(DataContext.java= :951) > =09at org.apache.cayenne.BaseContext.select(BaseContext.java:302) > =09at org.apache.cayenne.access.DataContextPrefetchMultistepTest.testToMa= nyToOne_EmptyToMany_NoRootQualifier(DataContextPrefetchMultistepTest.java:3= 00) > =09at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > =09at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImp= l.java:39) > =09at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcc= essorImpl.java:25) > =09at java.lang.reflect.Method.invoke(Method.java:597) > =09at junit.framework.TestCase.runTest(TestCase.java:154) > =09at junit.framework.TestCase.runBare(TestCase.java:127) > =09at junit.framework.TestResult$1.protect(TestResult.java:106) > =09at junit.framework.TestResult.runProtected(TestResult.java:124) > =09at junit.framework.TestResult.run(TestResult.java:109) > =09at junit.framework.TestCase.run(TestCase.java:118) > =09at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.ru= n(JUnit3TestReference.java:131) > =09at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecuti= on.java:38) > =09at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(Rem= oteTestRunner.java:467) > =09at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(Rem= oteTestRunner.java:683) > =09at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTe= stRunner.java:390) > =09at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteT= estRunner.java:197) -- This message was sent by Atlassian JIRA (v6.2#6252)