Another way to refresh an object, including the content of its relationships
(but not the contents of the related objects) is this:
context.invalidateObjects(Collections.singleton(myObject));
This may be more in line of what you are trying to do.
Andrus
On Sep 2, 2011, at 1:59 PM, Andrus Adamchik wrote:
> 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
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>>>
>>>
>>>
>
>