persistence@glassfish.java.net

Re: JPQL: create ReadAllQuery for simple SELECT queries

From: Michael Bouschen <Michael.Bouschen_at_Sun.COM>
Date: Tue, 28 Nov 2006 21:06:46 +0100

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
>>
>>
>>
>