I'll ask few questions, just to be sure:
- are you using named queries (ie. when fetching the alerts)
- are you using the same context when creating alert and when
checking for the alerts ?
If the latter try to use different context. And to be 100% sure in
the second query do query.setCachingPolicy(SelectQuery.NO_CHACHE);
See if that helps.
Regards
Marcin
On 20/05/2006, at 11:35 AM, Jeff de Vries wrote:
It didn't make any difference. (I was so sure it *would* make a
difference I ran it three times and double-checked everything each
time).
Looking at the SQL log, it looks like I oversimplified the
description of the problem (sorry). There is actual another table
involved, Listing, and the status that is being updated is in
Listing, not in Alert, though the Listing is being accessed through
the Alert (Alert has a foreign key referencing the Listing). So,
let me try again to describe the sequence of steps that are used to
update the database:
1) Using a given Listing, we SELECT all Alerts that refer to that
Listing. (In the case I'm looking at there is only one Alert).
2) Start transaction (i.e. there is a (unnecessary?) commit after
the previous SELECT)
3) INSERT a new Alert that references the existing Listing (note
that at this point the Listing has not been updated yet, i.e. it
still has the old status) and the Person the Alert is addressed to.
4) UPDATE the first Alert to indicate it has been processed (i.e.
set a 'seen' column to 'true')
5) UPDATE the status in the Listing to the new status (this is the
thing we're seeing the old version of later)
6) COMMIT changes.
Later, we do the following:
1) SELECT all Alerts addressed to this Person (which includes the
new Alert created in step 3 above; this is also the query to which
we added setRefreshingObjects = true, which now looks unnecessary
since we did get the new Alert even before making that change)
2) For each Alert, display the status of the Listing referenced by
that Alert. Note that at this point in the SQL log I don't see any
SELECT statements trying to retrieve Listing data, so I'm guessing
Cayenne thinks it already knows all the associated Listings and
their statuses. It looks like it is the relationship between Alert
and Listing that needs to be refreshed?
3) The status for the Listing associated with the new Alert still
shows the value it had before it was updated in step 5 above.
So, is it possible that when the new Alert is created it is
pointing at the original version of the Listing (I'm talking about
the in-memory objects, not the rows out in the database), but when
the Listing is updated the in-cache version isn't getting updated?
Or the in-cache version is getting updated, but the Alert is
pointing at a stale Listing object?
Thanks for the help!
Jeff
Marcin Skladaniec wrote:
You can try:
DataContext dc = DataContext.getThreadDataContext();
SelectQuery query = new SelectQuery(alert_subclass);
...
query.setRefreshingObjects(true);
...
List result = dc.performQuery(query);
Regards
Marcin
On 20/05/2006, at 8:05 AM, Jeff de Vries wrote:
I get the following compile error (I'm using Cayenne 1.2):
The method performQuery(Query) in the type DataContext is not
applicable for the arguments (SelectQuery, boolean)
I tried to find something equivalent for Cayenne 1.2 but didn't
recognize anything.
Gentry, Michael (Contractor) wrote:
Could you try: List result = dc.performQuery(query, true); And
see if it works better? Thanks, /dev/mrg -----Original
Message----- From: Jeff de Vries [mailto:[EMAIL PROTECTED]
Sent: Friday, May 19, 2006 12:18 PM To: cayenne-
[EMAIL PROTECTED] Subject: Re: Caching problem? It's
pretty straightforward. In the following code Person is the
parent, and Alert is the child. There are actually many Alert
classes (I'm using Cayenne STI), so the specific Alert class
we're interested in is passed as a parameter. Also, I forgot to
mention that if we shut everything down, and then restart, we do
see the modified status (presumably because Cayenne really had
to go back to the database to get the data for the child list). /
** * Finds all Alerts of the given type sent to the given person
* * @param person * Person to find Alerts for * @param
include_hidden * If true, include hidden alerts as well * @param
alert_subclass * Class of alert to search for * @return List of
alert objects, of given type, for the given person */ protected
static List findFor(Person person, boolean include_hidden, Class
alert_subclass) { DataContext dc =
DataContext.getThreadDataContext(); SelectQuery query = new
SelectQuery(alert_subclass); query.setQualifier
(ExpressionFactory.matchExp("toReceiver", person));
query.andQualifier(ExpressionFactory.matchExp("deleted", new
Boolean (false))); if (!include_hidden) query.andQualifier
(ExpressionFactory.matchExp("hidden",new Boolean (false)));
query.addOrdering("createDate",false); List result =
dc.performQuery(query); return result; } On May 19, 2006, at
6:05 AM, Gentry, Michael ((Contractor)) wrote:
Jeff, could you post the code where you are doing the second
query? Thanks! /dev/mrg -----Original Message----- From: Jeff
de Vries [mailto:[EMAIL PROTECTED] Sent: Friday, May 19, 2006
12:09 AM To: [email protected] Subject: Caching
problem? Simplified version: I have a parent table and a child
table, where the child table has a parent_id column and a
status column. I change the status in one of the child records
and commit the change. Later, I ask for the child records for
the given parent record, but the child record that I get back
on which I changed the status still has the *old* status
instead of the new status. If I look at the database, the child
record does have the new status (and in fact I can see the
update and commit as soon as I commit the child record change).
Why is the parent still seeing the old child status? An
additional note is that I'm not using parent.getChildArray()
but rather a SelectQuery(Child) that matches toParent to the
parent I'm interested in. (This is in Cayenne 1.2B2 using
PostgreSQL 8.1) Thanks, Jeff