persistence@glassfish.java.net

Re: Is it legal to have a JPQL query that has multiple LEFT JOIN FETCHes?

From: Michael Bouschen <Michael.Bouschen_at_Sun.COM>
Date: Tue, 20 Feb 2007 16:24:39 +0100

Hi Jon,

some more news:

I have the feeling you are running into the same problem as recently
described in issue 2440. The details can be found in the form post
http://forums.java.net/jive/thread.jspa?threadID=23213.
The user talks about a different query, an aggregate query. However, he
is running into a NPE when changing the query into a LEFT JOIN query and
the stacktrace is the same as in your case.

Now my question: is subItems a ManyToMany relationship from Item to
Item? If yes, it is likely you are running into the same issue and then
there is no need to file a new issue for this. I could reproduced the
NPE after changing my test case from a OneToMany to a ManyToMany
relationship to the same class.

Thanks!

Regards Michael

> Hi Jon,
>
> I tried to reproduce the NPE using a similar LEFT JOIN FETCH query,
> but it works on my side. I also tried joining a OneToMany relationship
> of the same class similar what you did with the i.subItems, but I'm
> not able to reproduce the NPE.
>
> Could you please file an issue at
> https://glassfish.dev.java.net/servlets/ProjectIssues using
> entity-persistence as subcomponent. It would be great if you could
> attach a test case to the issue that allows us to reproduce the NPE.
>
> Thanks!
>
> Regards Michael
>
>> Thanks Tom. The following is the exact query and stack trace. If I
>> left join to i.reservations instead of i.subItems it works fine. i.e.
>> maybe it has something to do with the fact that it's joining to itself?
>>
>> Feb 19, 2007 3:53:04 PM
>> edu.uchicago.at.reservations.ReservationsService findAvailableItems
>> FINEST: SELECT i FROM Item i LEFT JOIN FETCH i.subItems ORDER BY i.name
>> Feb 19, 2007 3:53:04 PM
>> oracle.toplink.essentials.session.file:/J:/Reservations/ReservationsLibrary/build/classes/-Reservations
>>
>> WARNING:
>> java.lang.NullPointerException
>> at
>> oracle.toplink.essentials.internal.expressions.SQLSelectStatement.appendFromClauseForOuterJoin(SQLSelectStatement.java:347)
>>
>> at
>> oracle.toplink.essentials.internal.expressions.SQLSelectStatement.appendFromClauseToWriter(SQLSelectStatement.java:452)
>>
>> at
>> oracle.toplink.essentials.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1310)
>>
>> at
>> oracle.toplink.essentials.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:683)
>>
>> at
>> oracle.toplink.essentials.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:548)
>>
>> at
>> oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:393)
>>
>> at
>> oracle.toplink.essentials.internal.queryframework.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1379)
>>
>> at
>> oracle.toplink.essentials.queryframework.ReportQuery.prepareSelectAllRows(ReportQuery.java:988)
>>
>> at
>> oracle.toplink.essentials.queryframework.ReadAllQuery.prepare(ReadAllQuery.java:398)
>>
>> at
>> oracle.toplink.essentials.queryframework.ReportQuery.prepare(ReportQuery.java:904)
>>
>> at
>> oracle.toplink.essentials.queryframework.DatabaseQuery.checkPrepare(DatabaseQuery.java:387)
>>
>> at
>> oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:469)
>>
>> at
>> oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:587)
>>
>> at
>> oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:677)
>>
>> at
>> oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:731)
>>
>> at
>> oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2219)
>>
>> at
>> oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937)
>>
>> at
>> oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
>>
>> at
>> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:335)
>>
>> at
>> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.getResultList(EJBQueryImpl.java:442)
>>
>> at
>> edu.uchicago.at.reservations.ReservationsService.findAvailableItems(ReservationsService.java:61)
>>
>> at
>> edu.uchicago.at.reservations.ReservationsServiceTest.testFindAvailableItems(ReservationsServiceTest.java:91)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:585)
>> at junit.framework.TestCase.runTest(TestCase.java:154)
>> at junit.framework.TestCase.runBare(TestCase.java:127)
>> at junit.framework.TestResult$1.protect(TestResult.java:106)
>> at junit.framework.TestResult.runProtected(TestResult.java:124)
>>
>> Jon
>>
>> ----- Original Message ----- From: "Tom Ware" <tom.ware_at_Oracle.com>
>> To: <persistence_at_glassfish.dev.java.net>
>> Sent: Monday, February 19, 2007 3:27 PM
>> Subject: Re: Is it legal to have a JPQL query that has multiple LEFT
>> JOIN FETCHes?
>>
>>
>>> Hi Jon,
>>>
>>> I am a bit surprised you are seeing an issue with the query you
>>> list below.
>>>
>>> Our test framework has some similar queries that work. For instance:
>>>
>>> "SELECT e from Employee e JOIN FETCH e.projects"
>>>
>>> Is the exception trace for your current query the same as for the
>>> previous query?
>>>
>>> BTW: I took a quick look at the BNF for JPQL and it seems your
>>> double joining query is not legal. JPQL requires a
>>> range_variable_declaration for each fetch join. That means:
>>> Item i LEFT JOIN FETCH i.reservations
>>>
>>> Is Legal
>>>
>>> And the second part:
>>>
>>> LEFT JOIN FETCH i.subItems
>>> Is missing something. (you can't join to "Item i" from the previous
>>> clause)
>>>
>>> -Tom
>>>
>>>
>>> Jon Miller wrote:
>>>
>>>> I just tried the following which throws a NPE too. So, it looks
>>>> like it's probably the fact that I'm mapping to the same class
>>>> rather than the fact that I had two LEFT JOINs which is what I
>>>> thought might have been the original problem. Is this a bug?
>>>>
>>>> SELECT i FROM Item i LEFT JOIN FETCH i.subItems ORDER BY i.name
>>>>
>>>> Jon
>>>>
>>>
>>> --
>>> Tom Ware
>>> Principal Software Engineer
>>> Oracle Canada Inc.
>>>
>>> Direct: (613) 783-4598
>>> Email: tom.ware_at_oracle.com
>>>