On 20/05/2006, at 2:25 PM, Jeff de Vries wrote:
Named queries? - No (is there a problem with named queries?)
There is no problem with named queries. I was asking, as those
queries are (I think) cached by default.
Same context? - Maybe. This is a web app, and the alert is created
during one http request, while the check is on a subsequent http
request. Since the data context is being bound to the thread, it
would depend on whether the same thread handled both requests. How
can I create a new (different) data context if I want to make sure
it is different than the original data context? BTW, this problem
is repeatable, so if the problem is using the same data context,
then it would appear that the same thread is being used for both
http requests.
To create new context :
Configuration.initializeSharedConfiguration();
Configuration conf = Configuration.getSharedConfiguration();
dataDomain = conf.getDomain();
dataContext = dataDomain.createDataContext();
Let me know how it goes.
Marcin
Marcin Skladaniec wrote:
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