I hate to cross-post this, but I've done some more tinkering and I'm
pretty sure this qualifies as a serious bug in the way prefetches are
currently handled.
The problem is that if you perform a prefetch on a relationship that
is also part of a query expression, the prefetched relationship is
incorrectly filtered. This is dangerous because the query root is
returned in a COMMITTED state with no relationship fault, giving the
impression that it accurately represents what is in the repository. As
far as I can tell, there is no indication that the relationship is
potentially incomplete, nor is there a way to fill in the "gaps".
Since the current way prefetches are handled works as long as the
query expression does not overlap, I see a couple of ways to handle
this...
1. The prefetch could be removed (with a WARN log event)
2. The relationship could be left as a fault, with the objects that
were prefetched pre-resolved
3. A subselect (or select ... in) could be used on supported database adapters.
To me, the latter option is ideal, but I'm not sure if all of the DBMS
support it.
---------- Forwarded message ----------
From: Cris Daniluk <cris.danilu..mail.com>
Date: Apr 28, 2005 1:53 PM
Subject: filtered prefetches
To: cayenne-use..bjectstyle.org
I'm currently using an expression to query for Users based on Roles
(through a UserRole join table) as such:
SelectQuery userSearchQuery = new SelectQuery(User.class,
ExpressionFactory.matchExp("toUserRole.toRoleArray", searchRole));
userSearchQuery.addPrefetch("toUserRole");
The search works as expected, but the prefetch does not. Cayenne is
applying the Expression from the base query to the prefetch:
SELECT DISTINCT t0.TX_FIRST_NAME, t0.TX_LAST_NAME, t0.TX_LOGIN_NAME,
t0.NU_USER_ID FROM USER t0, USER_ROLE t1 WHERE t0.NU_USER_ID =
t1.NU_USER_ID AND ((t1.NU_ROLE_ID = ?) AND (UPPER(t0.TX_LOGIN_NAME)
LIKE UPPER(?))) [bind: 0, 'cris']
=== returned 1 row. - took 141 ms.
SELECT t0.NU_ROLE_ID, t0.NU_USER_ID FROM USER_ROLE t0, USER t1 WHERE
t0.NU_USER_ID = t1.NU_USER_ID AND ((t0.NU_ROLE_ID = ?) AND
(UPPER(t1.TX_LOGIN_NAME) LIKE UPPER(?))) [bind: 0, 'cris']
=== returned 1 row. - took 93 ms.
The prefetch should contain all roles for the matching users, not just
the ones that were used in selecting the user. The behavior makes
sense based on how prefetches were done, but this really seems like a
bug to me...
Cris
This archive was generated by hypermail 2.0.0 : Fri Apr 29 2005 - 16:00:41 EDT