You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Chris Gamache <cg...@gmail.com> on 2008/06/09 22:08:53 UTC

Help! I need the magic no-cache recipe

Using Cayenne 2.0.3 ...

I'm having problems when I use an accessor to get rows from a related
table. It pulls fresh data the first time I use the accessor, but if
data is modified outside of the Java application, it is not reflected
the next time I use the accessor in a different execution stack within
the same JVM.

List rowsA = context.performQuery(someQuery);
...
SomeTable dataSetA = rowA.getRelatedRows();
//object rowA and dataSetA and someQuery pass out of scope
...
//Data is Modified directly on the database, not in Java application
...
List rowsB = context.performQuery(theSameQuery);
...
SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();


The primary key which the relation uses to get the related data
doesn't change from rowsA to rowsB. We're looking at the same related
rowset, just updated data.

I would like to know what is the magic no-cache recipe to force that
particular accessor to always pull fresh data from the database...

It appears that SelectQuery doesn't suffer from the same problem.

I'm sure there's some configuration switches that I can trip, but
there are several places caching policies can be modified and several
confusingly similar yet different options to choose from.

Re: Help! I need the magic no-cache recipe

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Chris,


On Jul 8, 2008, at 3:59 PM, Chris Gamache wrote:
> I can now say, beyond a shadow of a doubt, that cayenne is caching
> relational requests when the same keys are used to retrieve the  
> parent data
> object.

Yeah, each object within a DataContext is guaranteed to exist as a  
single instance, so all its relationships will be preserved, even if  
it is fetched multiple times, unless you use prefetching.

> The rows returned from the toMany request are volatile, and need to
> be re-queried when a new SelectQuery is run.


You need to use prefetching.


>> someQuery.addPrefetch("thisRelationIsaToManyList");
>> context.execute(someQuery); //throws ClassCastException in the part  
>> of
>> the code where it is trying to prefetch.
>>
>> How do I make certain the cayenne is not caching data from a relation
>> that returns a ToManyList? Probably not addPrefetch() because it
>> throws a ClassCastException.

Prefetching works. I guess you used the wrong prefetch key that caused  
the error, but that's no reason to give up. The string you pass to  
"addPrefetch" must be a relationship name for the entity that is a  
root of the query.

Andrus


Re: Help! I need the magic no-cache recipe

Posted by Chris Gamache <cg...@gmail.com>.
Any ideas on a solution to this problem?

I can now say, beyond a shadow of a doubt, that cayenne is caching
relational requests when the same keys are used to retrieve the parent data
object. The rows returned from the toMany request are volatile, and need to
be re-queried when a new SelectQuery is run.

Please advise. This has moved to a critical deficiency in my application. It
is always possible that the problem exists between the keyboard and the
chair. Please help me understand how to force Cayenne to exhibit the desired
behavior.


On Wed, Jun 18, 2008 at 3:57 PM, Chris Gamache <cg...@gmail.com> wrote:

> I'm sorry. I definitely was vague!!! Let me try again...
>
> someQuery.addPrefetch("thisRelationIsaToManyList");
> context.execute(someQuery); //throws ClassCastException in the part of
> the code where it is trying to prefetch.
>
> How do I make certain the cayenne is not caching data from a relation
> that returns a ToManyList? Probably not addPrefetch() because it
> throws a ClassCastException.
>
>
> On Wed, Jun 18, 2008 at 12:25 PM, Robert Zeigler
> <ro...@puregumption.com> wrote:
> > A ToManyList isn't a DataObject.  It's a list of DataObjects. :)
> > Just treat it like a regular list.
> >
> > Robert
> >
> > On Jun 18, 2008, at 6/1811:18 AM , Chris Gamache wrote:
> >
> >> also........ :)
> >>
> >> How do I deal with a ToManyList prefetch?
> >>
> >> I'm getting a ClassCastException trying to cast a ToManyList to a
> >> DataObject.
> >>
> >> On Mon, Jun 16, 2008 at 10:36 AM, Chris Gamache <cg...@gmail.com>
> >> wrote:
> >>>
> >>> For clarification:
> >>>
> >>> DataContext.invalidateObjects(...) What strategy would you use to
> >>> invalidate everything?
> >>>
> >>> For .addPrefetch(String s), does s need to match the relation name in
> >>> the xml files?
> >>>
> >>> And on a related note...
> >>>
> >>> What does "Max. Number of Shared Objects" actually limit, and what
> >>> does the "Use Shared Cache" toggle do?
> >>>
> >>> If I set my "Max. Number of Shared Objects" to zero, or unchecked "Use
> >>> Shared Cache" would that force Cayenne to hit the database every time
> >>> a query was executed or a relation was fetched?
> >>>
> >>>
> >>>
> >>>
> >>> On Tue, Jun 10, 2008 at 3:03 AM, Andrus Adamchik <
> andrus@objectstyle.org>
> >>> wrote:
> >>>>
> >>>> To control relationship refresh you can either use
> >>>> DataContext.invalidateObjects(..) or plan a bit ahead and refresh it
> >>>> together with the query that fetched the root object by using
> >>>> prefetching on
> >>>> that relationship. E.g.
> >>>>
> >>>> someQuery.addPrefetch("relatedRows");
> >>>> List rows = context.performQuery(someQuery);
> >>>>
> >>>> Judging from your example the prefetch option should be exactly what
> you
> >>>> need.
> >>>>
> >>>> Andrus
> >>>>
> >>>>
> >>>> On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
> >>>>>
> >>>>> Using Cayenne 2.0.3 ...
> >>>>>
> >>>>> I'm having problems when I use an accessor to get rows from a related
> >>>>> table. It pulls fresh data the first time I use the accessor, but if
> >>>>> data is modified outside of the Java application, it is not reflected
> >>>>> the next time I use the accessor in a different execution stack
> within
> >>>>> the same JVM.
> >>>>>
> >>>>> List rowsA = context.performQuery(someQuery);
> >>>>> ...
> >>>>> SomeTable dataSetA = rowA.getRelatedRows();
> >>>>> //object rowA and dataSetA and someQuery pass out of scope
> >>>>> ...
> >>>>> //Data is Modified directly on the database, not in Java application
> >>>>> ...
> >>>>> List rowsB = context.performQuery(theSameQuery);
> >>>>> ...
> >>>>> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
> >>>>>
> >>>>>
> >>>>> The primary key which the relation uses to get the related data
> >>>>> doesn't change from rowsA to rowsB. We're looking at the same related
> >>>>> rowset, just updated data.
> >>>>>
> >>>>> I would like to know what is the magic no-cache recipe to force that
> >>>>> particular accessor to always pull fresh data from the database...
> >>>>>
> >>>>> It appears that SelectQuery doesn't suffer from the same problem.
> >>>>>
> >>>>> I'm sure there's some configuration switches that I can trip, but
> >>>>> there are several places caching policies can be modified and several
> >>>>> confusingly similar yet different options to choose from.
> >>>>>
> >>>>
> >>>>
> >>>
> >
> >
>

Re: Help! I need the magic no-cache recipe

Posted by Chris Gamache <cg...@gmail.com>.
I'm sorry. I definitely was vague!!! Let me try again...

someQuery.addPrefetch("thisRelationIsaToManyList");
context.execute(someQuery); //throws ClassCastException in the part of
the code where it is trying to prefetch.

How do I make certain the cayenne is not caching data from a relation
that returns a ToManyList? Probably not addPrefetch() because it
throws a ClassCastException.


On Wed, Jun 18, 2008 at 12:25 PM, Robert Zeigler
<ro...@puregumption.com> wrote:
> A ToManyList isn't a DataObject.  It's a list of DataObjects. :)
> Just treat it like a regular list.
>
> Robert
>
> On Jun 18, 2008, at 6/1811:18 AM , Chris Gamache wrote:
>
>> also........ :)
>>
>> How do I deal with a ToManyList prefetch?
>>
>> I'm getting a ClassCastException trying to cast a ToManyList to a
>> DataObject.
>>
>> On Mon, Jun 16, 2008 at 10:36 AM, Chris Gamache <cg...@gmail.com>
>> wrote:
>>>
>>> For clarification:
>>>
>>> DataContext.invalidateObjects(...) What strategy would you use to
>>> invalidate everything?
>>>
>>> For .addPrefetch(String s), does s need to match the relation name in
>>> the xml files?
>>>
>>> And on a related note...
>>>
>>> What does "Max. Number of Shared Objects" actually limit, and what
>>> does the "Use Shared Cache" toggle do?
>>>
>>> If I set my "Max. Number of Shared Objects" to zero, or unchecked "Use
>>> Shared Cache" would that force Cayenne to hit the database every time
>>> a query was executed or a relation was fetched?
>>>
>>>
>>>
>>>
>>> On Tue, Jun 10, 2008 at 3:03 AM, Andrus Adamchik <an...@objectstyle.org>
>>> wrote:
>>>>
>>>> To control relationship refresh you can either use
>>>> DataContext.invalidateObjects(..) or plan a bit ahead and refresh it
>>>> together with the query that fetched the root object by using
>>>> prefetching on
>>>> that relationship. E.g.
>>>>
>>>> someQuery.addPrefetch("relatedRows");
>>>> List rows = context.performQuery(someQuery);
>>>>
>>>> Judging from your example the prefetch option should be exactly what you
>>>> need.
>>>>
>>>> Andrus
>>>>
>>>>
>>>> On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
>>>>>
>>>>> Using Cayenne 2.0.3 ...
>>>>>
>>>>> I'm having problems when I use an accessor to get rows from a related
>>>>> table. It pulls fresh data the first time I use the accessor, but if
>>>>> data is modified outside of the Java application, it is not reflected
>>>>> the next time I use the accessor in a different execution stack within
>>>>> the same JVM.
>>>>>
>>>>> List rowsA = context.performQuery(someQuery);
>>>>> ...
>>>>> SomeTable dataSetA = rowA.getRelatedRows();
>>>>> //object rowA and dataSetA and someQuery pass out of scope
>>>>> ...
>>>>> //Data is Modified directly on the database, not in Java application
>>>>> ...
>>>>> List rowsB = context.performQuery(theSameQuery);
>>>>> ...
>>>>> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
>>>>>
>>>>>
>>>>> The primary key which the relation uses to get the related data
>>>>> doesn't change from rowsA to rowsB. We're looking at the same related
>>>>> rowset, just updated data.
>>>>>
>>>>> I would like to know what is the magic no-cache recipe to force that
>>>>> particular accessor to always pull fresh data from the database...
>>>>>
>>>>> It appears that SelectQuery doesn't suffer from the same problem.
>>>>>
>>>>> I'm sure there's some configuration switches that I can trip, but
>>>>> there are several places caching policies can be modified and several
>>>>> confusingly similar yet different options to choose from.
>>>>>
>>>>
>>>>
>>>
>
>

Re: Help! I need the magic no-cache recipe

Posted by Robert Zeigler <ro...@puregumption.com>.
A ToManyList isn't a DataObject.  It's a list of DataObjects. :)
Just treat it like a regular list.

Robert

On Jun 18, 2008, at 6/1811:18 AM , Chris Gamache wrote:

> also........ :)
>
> How do I deal with a ToManyList prefetch?
>
> I'm getting a ClassCastException trying to cast a ToManyList to a  
> DataObject.
>
> On Mon, Jun 16, 2008 at 10:36 AM, Chris Gamache <cg...@gmail.com>  
> wrote:
>> For clarification:
>>
>> DataContext.invalidateObjects(...) What strategy would you use to
>> invalidate everything?
>>
>> For .addPrefetch(String s), does s need to match the relation name in
>> the xml files?
>>
>> And on a related note...
>>
>> What does "Max. Number of Shared Objects" actually limit, and what
>> does the "Use Shared Cache" toggle do?
>>
>> If I set my "Max. Number of Shared Objects" to zero, or unchecked  
>> "Use
>> Shared Cache" would that force Cayenne to hit the database every time
>> a query was executed or a relation was fetched?
>>
>>
>>
>>
>> On Tue, Jun 10, 2008 at 3:03 AM, Andrus Adamchik <andrus@objectstyle.org 
>> > wrote:
>>> To control relationship refresh you can either use
>>> DataContext.invalidateObjects(..) or plan a bit ahead and refresh it
>>> together with the query that fetched the root object by using  
>>> prefetching on
>>> that relationship. E.g.
>>>
>>> someQuery.addPrefetch("relatedRows");
>>> List rows = context.performQuery(someQuery);
>>>
>>> Judging from your example the prefetch option should be exactly  
>>> what you
>>> need.
>>>
>>> Andrus
>>>
>>>
>>> On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
>>>>
>>>> Using Cayenne 2.0.3 ...
>>>>
>>>> I'm having problems when I use an accessor to get rows from a  
>>>> related
>>>> table. It pulls fresh data the first time I use the accessor, but  
>>>> if
>>>> data is modified outside of the Java application, it is not  
>>>> reflected
>>>> the next time I use the accessor in a different execution stack  
>>>> within
>>>> the same JVM.
>>>>
>>>> List rowsA = context.performQuery(someQuery);
>>>> ...
>>>> SomeTable dataSetA = rowA.getRelatedRows();
>>>> //object rowA and dataSetA and someQuery pass out of scope
>>>> ...
>>>> //Data is Modified directly on the database, not in Java  
>>>> application
>>>> ...
>>>> List rowsB = context.performQuery(theSameQuery);
>>>> ...
>>>> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
>>>>
>>>>
>>>> The primary key which the relation uses to get the related data
>>>> doesn't change from rowsA to rowsB. We're looking at the same  
>>>> related
>>>> rowset, just updated data.
>>>>
>>>> I would like to know what is the magic no-cache recipe to force  
>>>> that
>>>> particular accessor to always pull fresh data from the database...
>>>>
>>>> It appears that SelectQuery doesn't suffer from the same problem.
>>>>
>>>> I'm sure there's some configuration switches that I can trip, but
>>>> there are several places caching policies can be modified and  
>>>> several
>>>> confusingly similar yet different options to choose from.
>>>>
>>>
>>>
>>


Re: Help! I need the magic no-cache recipe

Posted by Chris Gamache <cg...@gmail.com>.
also........ :)

How do I deal with a ToManyList prefetch?

I'm getting a ClassCastException trying to cast a ToManyList to a DataObject.

On Mon, Jun 16, 2008 at 10:36 AM, Chris Gamache <cg...@gmail.com> wrote:
> For clarification:
>
> DataContext.invalidateObjects(...) What strategy would you use to
> invalidate everything?
>
> For .addPrefetch(String s), does s need to match the relation name in
> the xml files?
>
> And on a related note...
>
> What does "Max. Number of Shared Objects" actually limit, and what
> does the "Use Shared Cache" toggle do?
>
> If I set my "Max. Number of Shared Objects" to zero, or unchecked "Use
> Shared Cache" would that force Cayenne to hit the database every time
> a query was executed or a relation was fetched?
>
>
>
>
> On Tue, Jun 10, 2008 at 3:03 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
>> To control relationship refresh you can either use
>> DataContext.invalidateObjects(..) or plan a bit ahead and refresh it
>> together with the query that fetched the root object by using prefetching on
>> that relationship. E.g.
>>
>> someQuery.addPrefetch("relatedRows");
>> List rows = context.performQuery(someQuery);
>>
>> Judging from your example the prefetch option should be exactly what you
>> need.
>>
>> Andrus
>>
>>
>> On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
>>>
>>> Using Cayenne 2.0.3 ...
>>>
>>> I'm having problems when I use an accessor to get rows from a related
>>> table. It pulls fresh data the first time I use the accessor, but if
>>> data is modified outside of the Java application, it is not reflected
>>> the next time I use the accessor in a different execution stack within
>>> the same JVM.
>>>
>>> List rowsA = context.performQuery(someQuery);
>>> ...
>>> SomeTable dataSetA = rowA.getRelatedRows();
>>> //object rowA and dataSetA and someQuery pass out of scope
>>> ...
>>> //Data is Modified directly on the database, not in Java application
>>> ...
>>> List rowsB = context.performQuery(theSameQuery);
>>> ...
>>> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
>>>
>>>
>>> The primary key which the relation uses to get the related data
>>> doesn't change from rowsA to rowsB. We're looking at the same related
>>> rowset, just updated data.
>>>
>>> I would like to know what is the magic no-cache recipe to force that
>>> particular accessor to always pull fresh data from the database...
>>>
>>> It appears that SelectQuery doesn't suffer from the same problem.
>>>
>>> I'm sure there's some configuration switches that I can trip, but
>>> there are several places caching policies can be modified and several
>>> confusingly similar yet different options to choose from.
>>>
>>
>>
>

Re: Help! I need the magic no-cache recipe

Posted by Chris Gamache <cg...@gmail.com>.
For clarification:

DataContext.invalidateObjects(...) What strategy would you use to
invalidate everything?

For .addPrefetch(String s), does s need to match the relation name in
the xml files?

And on a related note...

What does "Max. Number of Shared Objects" actually limit, and what
does the "Use Shared Cache" toggle do?

If I set my "Max. Number of Shared Objects" to zero, or unchecked "Use
Shared Cache" would that force Cayenne to hit the database every time
a query was executed or a relation was fetched?




On Tue, Jun 10, 2008 at 3:03 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
> To control relationship refresh you can either use
> DataContext.invalidateObjects(..) or plan a bit ahead and refresh it
> together with the query that fetched the root object by using prefetching on
> that relationship. E.g.
>
> someQuery.addPrefetch("relatedRows");
> List rows = context.performQuery(someQuery);
>
> Judging from your example the prefetch option should be exactly what you
> need.
>
> Andrus
>
>
> On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
>>
>> Using Cayenne 2.0.3 ...
>>
>> I'm having problems when I use an accessor to get rows from a related
>> table. It pulls fresh data the first time I use the accessor, but if
>> data is modified outside of the Java application, it is not reflected
>> the next time I use the accessor in a different execution stack within
>> the same JVM.
>>
>> List rowsA = context.performQuery(someQuery);
>> ...
>> SomeTable dataSetA = rowA.getRelatedRows();
>> //object rowA and dataSetA and someQuery pass out of scope
>> ...
>> //Data is Modified directly on the database, not in Java application
>> ...
>> List rowsB = context.performQuery(theSameQuery);
>> ...
>> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
>>
>>
>> The primary key which the relation uses to get the related data
>> doesn't change from rowsA to rowsB. We're looking at the same related
>> rowset, just updated data.
>>
>> I would like to know what is the magic no-cache recipe to force that
>> particular accessor to always pull fresh data from the database...
>>
>> It appears that SelectQuery doesn't suffer from the same problem.
>>
>> I'm sure there's some configuration switches that I can trip, but
>> there are several places caching policies can be modified and several
>> confusingly similar yet different options to choose from.
>>
>
>

Re: Help! I need the magic no-cache recipe

Posted by Andrus Adamchik <an...@objectstyle.org>.
To control relationship refresh you can either use  
DataContext.invalidateObjects(..) or plan a bit ahead and refresh it  
together with the query that fetched the root object by using  
prefetching on that relationship. E.g.

someQuery.addPrefetch("relatedRows");
List rows = context.performQuery(someQuery);

Judging from your example the prefetch option should be exactly what  
you need.

Andrus


On Jun 9, 2008, at 11:08 PM, Chris Gamache wrote:
> Using Cayenne 2.0.3 ...
>
> I'm having problems when I use an accessor to get rows from a related
> table. It pulls fresh data the first time I use the accessor, but if
> data is modified outside of the Java application, it is not reflected
> the next time I use the accessor in a different execution stack within
> the same JVM.
>
> List rowsA = context.performQuery(someQuery);
> ...
> SomeTable dataSetA = rowA.getRelatedRows();
> //object rowA and dataSetA and someQuery pass out of scope
> ...
> //Data is Modified directly on the database, not in Java application
> ...
> List rowsB = context.performQuery(theSameQuery);
> ...
> SomeTable expectedModifiedButGotSetA = rowB.getRelatedRows();
>
>
> The primary key which the relation uses to get the related data
> doesn't change from rowsA to rowsB. We're looking at the same related
> rowset, just updated data.
>
> I would like to know what is the magic no-cache recipe to force that
> particular accessor to always pull fresh data from the database...
>
> It appears that SelectQuery doesn't suffer from the same problem.
>
> I'm sure there's some configuration switches that I can trip, but
> there are several places caching policies can be modified and several
> confusingly similar yet different options to choose from.
>