In general a Cayenne user may be dealing with an object graph that can
potentially start at 1 entity and then span the entire DB (prefetches can be
multi-step). So Cayenne can't guess for you which relationships need to be
refreshed, without potentially incurring a gigantic query.
So it is still your responsibility as a user to tell it how much or how little
to prefetch. And you can do something dynamic. E.g. if you decide that all the
relationships you care about are only 1 level deep, you can find an ObjEntity
and iterate through all relationships to add prefetches:
SelectQuery q =
ObjEntity entity = context.getEntityResolver().lookupObjEntity(MyClass.class);
for(Relationship r : entity.getRelationships) {
q.addPrefetch(r.getName());
}
Andrus
On Sep 2, 2011, at 1:51 PM, Anthony Brew wrote:
> Hi Andrus,
> Yeah thats the most viable solution I have found so far, but
> tbh but from a code point of view here I think its a risky option as it
> could introduce bugs, it not all changing properties are added to the
> prefetch.
>
> query.addPrefetch(Item.SUB_ITEMS_PROPERTY);
>
> Would be nice to have a way when the NO_CACHE item is specified to make sure
> linked objects are pulled fresh also.
>
> Thanks a million for all your help.
> Anthony
>
> On Fri, Sep 2, 2011 at 6:04 PM, Andrus Adamchik <[email protected]>wrote:
>
>> To refresh a relationship, you may use a prefetch on the query:
>>
>>
>>
>>
>> Andrus
>>
>>
>> On Sep 2, 2011, at 12:51 PM, Joseph Senecal wrote:
>>
>>> I think the generated code for the getter() should always return the
>> existing list because that is the whole point of an ORM, to manage an object
>> graph in memory.
>>>
>>> But it should be easy to override that getter() method in the generated
>> subclass to always do an uncached query.
>>>
>>> Joe
>>>
>>> On Sep 2, 2011, at 9:45 AM, Mike Kienenberger wrote:
>>>
>>>> There may be a better way, but one obvious way this could be done is to
>>>> change the code generation so that the getter() executes a select query
>>>> rather than returning an existing list.
>>>>
>>>> On Fri, Sep 2, 2011 at 11:28 AM, Anthony Brew <[email protected]
>>> wrote:
>>>>
>>>>> Hi,
>>>>> Just an update, and I think I forgot to include something important
>>>>> Its a one to many relationship that I am seeing cached, (ie I fetch
>> "Item"
>>>>> and the many to one "Item.getSubItems()" are being fetched from the
>> cache)
>>>>>
>>>>> My code now looks a bit like:
>>>>>
>>>>> Expression e1 = Expression.fromString("id = $id");
>>>>> Map params = new HashMap();
>>>>> params.put("id", item.getId());
>>>>>
>>>>> SelectQuery query = new SelectQuery(Item.class,
>>>>> e1.expWithParameters(params));
>>>>> query.setCacheStrategy(QueryCacheStrategy.NO_CACHE);
>>>>>
>>>>> List items = context.performQuery(query);
>>>>> if(items.size() != 1){
>>>>> throw new RuntimeException("");
>>>>> }
>>>>> freshitem = (Item) items.get(0);
>>>>>
>>>>> subitems = freshitem.getSubItems()
>>>>>
>>>>> Where subitems are stale.
>>>>>
>>>>> I am sure I am making this more complicated than needs be. As I
>> mentioned
>>>>> before I would like to turn on some flag to essentially always read
>> from DB
>>>>> when I do items.getSubItems() if possible, or when I reload the Item
>> when
>>>>> its getter methods are called to make it always read from the DB the
>> first
>>>>> time when QueryCacheStrategy.NO_CACHE is specified...
>>>>>
>>>>> Thanks a Million,
>>>>> Anthony
>>>>>
>>>>>
>>>>> On Fri, Sep 2, 2011 at 3:54 PM, Mike Kienenberger <[email protected]
>>>>>> wrote:
>>>>>
>>>>>> You may want to review these two threads from the end of July:
>>>>>>
>>>>>> OSCache is gone
>>>>>> http://www.mail-archive.com/[email protected]/msg06209.html
>>>>>>
>>>>>> EhCache integration preview
>>>>>> http://www.mail-archive.com/[email protected]/msg06211.html
>>>>>>
>>>>>>
>>>>>> On Fri, Sep 2, 2011 at 10:30 AM, Anthony Brew <[email protected]
>>>>>>> wrote:
>>>>>>
>>>>>>> Hi Andrus,
>>>>>>> I was just about to get back to you on, I accidentally
>>>>>>> started two threads when I joined the mailing list.
>>>>>>>
>>>>>>> Essentially we have a ruby on rails project that creates config on
>> the
>>>>>>> front
>>>>>>> end, this is the part that is changing externally. Then internally we
>>>>>> read
>>>>>>> these config and do a bunch of processing and write the results to a
>>>>>>> separate set of tables. The tables are in turn read by the R on R app
>>>>> but
>>>>>>> never written to
>>>>>>>
>>>>>>> so
>>>>>>> Tables Set A | Set B
>>>>>>>
>>>>>
>> ------------------------------------------------------------------------
>>>>>>> Rails read and write | read only
>>>>>>> Java read only | read and write
>>>>>>>
>>>>>>> The issues I am facing are with set A changing in the app.
>>>>>>>
>>>>>>> I have tried forcing the Item to reload by doing this, (I cut code
>> from
>>>>>>> Cayennes: DataObjectUtils.objectForPK(threadDataContext,
>>>>> Item.class,
>>>>>>> dirtyItem.getId());)
>>>>>>>
>>>>>>> private Item getItemWithNoCayenneCache(Item newGame, DataContext
>>>>>>> threadDataContext) {
>>>>>>> ObjectId gameIdentifier = buildId(threadDataContext, Game.class,
>>>>>>> newGame.getId());
>>>>>>>
>>>>>>> return (Item) DataObjectUtils.objectForQuery(threadDataContext,
>>>>>> new
>>>>>>> ObjectIdQuery(
>>>>>>> gameIdentifier,
>>>>>>> false,
>>>>>>> ObjectIdQuery.CACHE_REFRESH));
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> stepping into *DataObjectUtils.objectForQuery stepping into the
>> Cayenne
>>>>>>> code
>>>>>>> I eventually get to DataContext.java*
>>>>>>> *
>>>>>>> *
>>>>>>> where I see the following method called
>>>>>>>
>>>>>>> *
>>>>>>> @Override
>>>>>>> @SuppressWarnings("unchecked")
>>>>>>> public List performQuery(Query query) {
>>>>>>> query = nonNullDelegate().willPerformQuery(this, query);
>>>>>>> if (query == null) {
>>>>>>> return new ArrayList<Object>(1);
>>>>>>> }
>>>>>>>
>>>>>>> List result = onQuery(this, query).firstList();
>>>>>>> return result != null ? result : new ArrayList<Object>(1);
>>>>>>> }
>>>>>>> *
>>>>>>>
>>>>>>> however i see that the delgate in *
>>>>>>> nonNullDelegate() is null and so I get back NoopDelegate.noopDelegate
>>>>>> which
>>>>>>> I assume is the route of my woes.
>>>>>>> *
>>>>>>> *
>>>>>>>
>>>>>>> *
>>>>>>> Im interested in trying the OSCache solution you proposed in my other
>>>>>>> thread, but I am a little wary the code is stale as my maven
>>>>> dependancies
>>>>>>> fail (I am actually pretty new to maven so this might be my bad).
>>>>>>> OSCache appears to be quite old since the OpenSymphony project died,
>>>>>> maybe
>>>>>>> my maven config is off, are there still active contributors?
>>>>>>>
>>>>>>> In my pom I have specified
>>>>>>> <dependency>
>>>>>>> <groupId>opensymphony</groupId>
>>>>>>> <artifactId>oscache</artifactId>
>>>>>>> <version>2.4</version>
>>>>>>> </dependency>
>>>>>>>
>>>>>>> however the dependancies on
>>>>>>>
>>>>>>> - javax.jms:jms:1.1
>>>>>>>
>>>>>>> Thanks a Million
>>>>>>> Anthony
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Sep 2, 2011 at 2:34 PM, Andrus Adamchik <
>>>>> [email protected]
>>>>>>>> wrote:
>>>>>>>
>>>>>>>> Could you please explain your data access patterns?
>>>>>>>>
>>>>>>>> E.g. if you fetch some objects and store them in an instance
>> variable
>>>>>> in
>>>>>>>> your application, they are not going to get refreshed automatically.
>>>>> To
>>>>>>>> refresh objects you need to either invalidate them explicitly via
>>>>>>>> context.invalidateObjects() or run a query. All the cache settings
>>>>> are
>>>>>>>> essentially about optimizing query execution (refresh data, but only
>>>>> as
>>>>>>>> often as needed).
>>>>>>>>
>>>>>>>> Andrus
>>>>>>>>
>>>>>>>> On Sep 2, 2011, at 9:28 AM, Anthony Brew wrote:
>>>>>>>>
>>>>>>>>> Hi Gary,
>>>>>>>>> Yeah thats what I am seeing in the code, but I cant for
>>>>>> the
>>>>>>>> life
>>>>>>>>> of me see how to turn off the caching completely in the modeller, I
>>>>>>>> actually
>>>>>>>>> think it wont hit our performance very badly to have no caching.
>>>>>>>>>
>>>>>>>>> The cache setting I see are the in the DataDomain Configuration
>>>>>>>>>
>>>>>>>>> Which has an option for a Query Cache Factory with a choice of two
>>>>>>>> classes.
>>>>>>>>> - org.apache.cayenne.cache.MapQueryCacheFactory
>>>>>>>>> - org.apache.cayenne.cache.OSQueryCacheFactory
>>>>>>>>>
>>>>>>>>> I selected the MapQueryCache and trie to set the size of the object
>>>>>>> cache
>>>>>>>> to
>>>>>>>>> 1 (couldn't set this to zero) as the application barfed saying
>>>>> caches
>>>>>>> had
>>>>>>>> to
>>>>>>>>> be greater than size zero.
>>>>>>>>>
>>>>>>>>> in my cayenne.xml I see the line
>>>>>>>>>
>>>>>>>>> <property name="cayenne.DataRowStore.snapshot.size" value="1"/>
>>>>>>>>>
>>>>>>>>> was added, perhaps there is some manual setting I can add to this
>>>>>> file
>>>>>>> to
>>>>>>>>> turn caching off?
>>>>>>>>>
>>>>>>>>> All the Best,
>>>>>>>>> Anthony
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Fri, Sep 2, 2011 at 12:20 AM, Gary Jarrel <[email protected]
>>>>>>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> I'd say that would be cache related, as Cayenne is caching the
>>>>> data
>>>>>>>>>> from the database, switch the cache of in the Modeler perhaps and
>>>>>> that
>>>>>>>>>> should fix your problem.
>>>>>>>>>>
>>>>>>>>>> G
>>>>>>>>>>
>>>>>>>>>> On Fri, Sep 2, 2011 at 3:04 AM, Anthony Brew <
>>>>>> [email protected]>
>>>>>>>>>> wrote:
>>>>>>>>>>> Hi,
>>>>>>>>>>> I have a two processes one which writes to a several database
>>>>>>> tables
>>>>>>>>>> (a
>>>>>>>>>>> ruby on rails application) and a java application that reads the
>>>>>>> state
>>>>>>>>>> these
>>>>>>>>>>> data base tables using Cayenne and writes to other tables.
>>>>>>>>>>>
>>>>>>>>>>> When the ruby modifies the underlying data-base I am seeing that
>>>>>>>> Cayenne
>>>>>>>>>> is
>>>>>>>>>>> not automatically picking up that the underlying data is now
>>>>>>>> inconsistant
>>>>>>>>>>> and not reloading. Is there some way I can config Cayenne to
>>>>>>> aggressive
>>>>>>>>>>> check some tables for updates while ignoring others?
>>>>>>>>>>>
>>>>>>>>>>> Thanks a Million
>>>>>>>>>>> Anthony Brew
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>
>>>
>>
>>