Hi Michael,
I found the reason for the fetch join issue. The way we are returning
items for the fetch join is actually dictated by the specification. (see
section 4.4.5.3)
What that means is that for the time being, we will likely have to
generate a ReportQuery on fetch join. I plan on entering an Enhancement
request to add a ReadAllQuery option that allows results to be returned
in the same way. At that time, we can update the JPQL parser.
I appologize for causing this extra work before it can actually be used.
-Tom
Michael Bouschen wrote:
>Hi Tom,
>
>good point! I was not aware of the other API
>addJoinedAttribute(Expression) that allows fetch join support for
>ReadAllQuerys.
>
>I changed the query compiler accordingly, such that it supports
>generating a ReadAllQuery with fetch joins. But now I run into a problem
>with one of the tests in entity-persistence-tests:
>JUnitEJBQLSimpleTestSuite.simpleJoinFetchTest. The test runs a JPQL
>fetch join query and compares the result against a TopLink ReportQuery.
>The ReportQuery result includes duplicated entities where the
>corresponding ReadAllQuery does not include duplicates.
>
>Attached you find a small test application showing the difference. It
>has two entity classes: Customer and Order. The test creates one
>Customer with two Order instances and persist them. It then runs a
>ReportQuery and a ReadAllQuery both representing the following JPQL
>query "SELECT c FROM Customer c JOIN FETCH c.orders". The generated SQL
>is equivalent (the identification variable names are swapped). But the
>ReportQuery returns the Customer twice, where the ReadAllQuery returns
>it only once. Here are the results:
>ReportQuery:
>- SQL
> SELECT DISTINCT t0.ID, t0.NAME, t1.ID, t1.TOTAL_PRICE,
>t1.CREATION_DATE, t1.CUST_ID
> FROM CUSTOMER_TABLE t0, ORDER_TABLE t1 WHERE (t1.CUST_ID = t0.ID)
>- Result [Customer(id=1, name=Michael), Customer(id=1, name=Michael)]
>
>ReadAllQuery:
>- SQL
> SELECT DISTINCT t1.ID, t1.NAME, t0.ID, t0.TOTAL_PRICE,
>t0.CREATION_DATE, t0.CUST_ID
> FROM ORDER_TABLE t0, CUSTOMER_TABLE t1 WHERE (t0.CUST_ID = t1.ID)
>- Result: [Customer(id=1, name=Michael)]
>
>The test uses ddl-generation. Please adapt the persistence.xml under
>src/META-INF to your environment, if you want to run the test.
>
>Regards Michael
>
>
>>Hi Michael,
>>
>> 'Just one comment.
>>
>> Fetch joins could be an issue since they are supported in
>>ReadAllQuery, but with different API. See
>>ObjectLevelReadQuery.addJoinedAttribute(Expression). How difficult
>>would it be to allow fetch joins to work on ReadAllQueries?
>>
>>-Tom
>>
>>Michael Bouschen wrote:
>>
>>
>>
>>>Hi Tom, hi Jielin,
>>>
>>>attached you find my changes to fix issue 1519 "JPQL: create a
>>>ReadAllQuery for simple queries":
>>>https://glassfish.dev.java.net/issues/show_bug.cgi?id=1519
>>>
>>>This change allows to map a simple SELECT query to a ReadAllQuery
>>>instance, where other SELECT queries are mapped to a ReportQuery. A
>>>query falls into the ReadAllQuery category, if
>>>- the SELECT clause consists of a single expression
>>>- the SELECT clause expression is an identification variable w/o
>>>projection (which means the query returns entities)
>>>- the identification variable is defined as range variable w/o FETCH
>>>JOINs and is the base of the generated TopLink query instance.
>>>
>>>Thanks!
>>>
>>>Regards Michael
>>>
>>>
>>>
>>>
>>>
>
>
>
--
Tom Ware
Principal Software Engineer
Oracle Canada Inc.
Direct: (613) 783-4598
Email: tom.ware_at_oracle.com