cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Lawrence Gerstley <>
Subject Re: Lifecycle Design
Date Sun, 12 Apr 2009 07:17:40 GMT
I'm feeling thick, but I'm really stuck with what is becoming an
increasingly simple attempt to convince myself that I can get the simplest
of caching examples working.
My attempt now is to get two machines on two separate JVMs to have a
force-reload. To do this, I'm re-running the query that populates on Content
Provider. The Cayenne Controller has these settings:

DataSource dataSource = new
PoolManager("com.mysql.jdbc.Driver", server, 1, 5, userId, password);
Configuration config = Configuration.getSharedConfiguration();
DataDomain domain = config.getDomain();
DataNode node = domain.getNode("AmerigoDomainNode");
DataMap dataMap = domain.getMap("AmerigoDomainMap");

All queries follow this pattern, roughly:
Expression express =
ExpressionFactory.likeIgnoreCaseExp( MisysDict.TEST_NAME_PROPERTY, nameMatch);
SelectQuery sq = new SelectQuery(MisysDict.class, express);
sq.setCacheGroups("grp1", "grp2", "grp3");

Now, I can update a row from either application, and see the change commit
in the data store. However, when I rerun the query above, the objects
attached to the returned objects remain in their old state. For example, the
entity MisysDict can return a list of Xrefs (MisysDict.getMisysRecToXREF():
<List>XREF). When I examine one of these XREFs, I cannot see any change made
to it from the other application. However, I *can* see changes made to the
MisysDict record itself.

I know I'm going to feel foolish for asking, but can you tell me what simple
thing(s) I'm off on here?

Thanks, as always,


On Sat, Apr 11, 2009 at 2:16 AM, Andrus Adamchik <>wrote:

> The caching docs are embarrassingly out of date. It's been requested a
> number of times to fix them. Maybe finally I'll do it...
> As for the cache strategy, you'd usually pick one of LOCAL_CACHE or
> SHARED_CACHE (or NO_CACHE for no caching, but that's the default already).
> Javadocs for QueryCacheStrategy explain each one of the strategies. Let me
> point to the differences between "LOCAL" and "SHARED" here. "Local" means
> attached to your ObjectContext, "Shared" - shared by all ObjectContext
> produced by a given Cayenne stack (usually this means shared by all contexts
> in a given JVM). Accessing shared cache is somewhat slower than local, so if
> you have a singleton DataContext (so DataContext is already shared by
> itself), select local cache.
> Andrus
> On Apr 11, 2009, at 3:31 AM, Joe Baldwin wrote:
>> Lawrence,
>> I am still struggling to understand Andrus' setCacheStrategy() approach in
>> his previous email (he claims it is simple and I am all for that :) ).  I am
>> attempting some black box testing to figure out exactly where my data object
>> is getting cached (and not updated properly).  In my case I am initializing
>> a class variable with DB data via Cayenne into a singleton when the class is
>> initially loaded.  I am not sure whether it is my design or execution of my
>> design that is at fault.
>>  strategies, but a simple Refresh All would get me across the line for the
>>> moment. Is there any info on this?
>> WRT your issue, I found this class in the 3.0 API:
>> The docs assert:
>>        "A query that allows to explicitly clear both object and list
>> caches either via refetch (eager refresh) or invalidate (lazy refresh)."
>> This may be the ticket for you.
>> Unfortunately, my singleton appears to be attached to the Tomcat app and
>> not the session so I can't find an elegant way for it to refresh.
>> Please let me know if you get this working.
>> Joe
>> On Apr 10, 2009, at 5:28 PM, Lawrence Gerstley wrote:
>>  So, in my knowledge-gaining journey with this topic, I ran across this
>>> page:, which looks like
>>> a list of items yet to be done or at least yet to be documented (and boy,
>>> when I have things really understood, I want to volunteer some documentation
>>> time to the project). There is a topic headline of "Refresh All", and an
>>> indication in the links posted as to the "RefreshQuery", but the pertinent
>>> part of the links are broken, and I can't track down the resolution of the
>>> items. However, this is exactly what I need to do for a first step. My
>>> application's environment will be (mandated by the customer), a thick client
>>> running on a Citrix instance, and some of the challenges posed by JGroups
>>> will take me awhile to understand. In the meantime, I want to provide a
>>> simple "Refresh All" button that will provide for a dumb refresh without
>>> leaving the application. I'm struggling with different caching strategies,
>>> but a simple Refresh All would get me across the line for the moment. Is
>>> there any info on this?
>>> Cheers,
>>> Lawrence
>>> On Apr 10, 2009, at 6:09 AM, Andrus Adamchik wrote:
>>>  As mentioned in the quoted docs, there are ways to receive immediate
>>>> notifications on the individual objects updates (if they are updated via
>>>> Cayenne). This approach, while the most powerful on the surface, is least
>>>> practical, especially across the VM. It suffers from a number of
>>>> shortcomings (as also have been mentioned here):
>>>> * It has a potential to generate too much network traffic
>>>> * As all update events are broadcast, it has a potential to DDOS the
>>>> apps who may not care about 90% of the updates (as all incoming events incur
>>>> processing overhead), so some manual event channel filtering may be needed.
>>>> * It does not correctly refresh cached query lists. E.g. if you have a
>>>> cached fetch for "documents that are in draft mode", and then received an
>>>> event saying that one of the drafts has changed to "not a draft", the object
>>>> will be refreshed, the list will become stale, as its composition no longer
>>>> matches the search criteria.
>>>> * Finally, the data can change in DB by non Cayenne clients...
>>>> So I am very much in favor of the Query Cache approach that is not
>>>> documented that well, but is really simple to use:
>>>> query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE); // or
>>>> query.setCacheGroups("g1", "g2", ...);
>>>> Once you start doing that for your queries, you can perform further
>>>> cache configuration in a semi-declarative manner. E.g. I am successfully
>>>> using OSQueryCacheFactory:
>>>> dataDomain.setQueryCacheFactory(new OSQueryCacheFactory());
>>>> This ties Cayenne query cache to OSCache which allows time based
>>>> expiration of entries, cron like expressions, and forced invalidation,
>>>> including remote invalidation via JGroups. All of that incurs nearly zero
>>>> overhead, as the entries are not actively purged from cache, but rather
>>>> marked as invalid by "group" (see 'setCacheGroups' above). Cross-VM events
>>>> are also sent as the names of the groups to invalidate, not full object
>>>> snapshots. This is very powerful and easy to use stuff.
>>>> Andrus
>>>> On Apr 10, 2009, at 10:17 AM, Andrey Razumovsky wrote:
>>>>> The proposed way is to use JGroups or JMS for synchronization:
>>>>> 2009/4/10 Lawrence Gerstley <>
>>>>>  So, I have the same question here--multiple thick clients (desktop RCP
>>>>>> applications), each with a DataContext tied to the same backend,
>>>>>> potential database access (direct or otherwise) from other toolsets
>>>>>> out of
>>>>>> my control. Is there a recommended strategy for refreshing each
>>>>>> applications
>>>>>> singleton DataContext to stay in synch, or manually a supplying
>>>>>> refresh
>>>>>> command to the DataContext to periodically update (and, if so, with
>>>>>> what/how)?
>>>>>> Kind regards,
>>>>>> Lawrence
>>>>>> ===================================
>>>>>> Lawrence Gerstley, Ph.D.
>>>>>> PSMI Consulting
>>>>>> Cel: (415) 694-0844
>>>>>> On Apr 8, 2009, at 4:22 PM, Malcolm Edgar wrote:
>>>>>> Hi Joe,
>>>>>>> Your singleton cache is going to need to be update periodically
>>>>>>> there are changes to the under lying database from other sources.
>>>>>>> regards Malcolm Edgar
>>>>>>> On Thu, Apr 9, 2009 at 7:45 AM, Joe Baldwin <
>>>>>>> >
>>>>>>> wrote:
>>>>>>>  I *think* this is a life-cycle question, but there may be more
>>>>>>>> it.
>>>>>>>> Proposed Design:
>>>>>>>> 1. Standard Web page JSP using Tomcat server.
>>>>>>>> 2. One of the JSP's accesses a singleton.
>>>>>>>> 3. The singleton accesses and stores a database field via
>>>>>>>> (presumably when the class is initially loaded) and should
>>>>>>>> need to
>>>>>>>> access the field again.
>>>>>>>> 4. I would prefer it if the database field change would be
>>>>>>>> propagated to
>>>>>>>> the
>>>>>>>> singleton upon the next new client-Session.
>>>>>>>> Problem
>>>>>>>> 1. Here is the odd bit: the database field can be modified
>>>>>>>> direct
>>>>>>>> access
>>>>>>>> to the database (SQL, etc).
>>>>>>>> 2. Cayenne appears not to see this change even when a new
>>>>>>>> client-Session
>>>>>>>> is
>>>>>>>> initialized.
>>>>>>>> 3. I can *force* the singleton to recognize the change by
>>>>>>>> Tomcat
>>>>>>>> (but that is totally lame :) )
>>>>>>>> 4. Unless I have made a mistake (which is possible), the
>>>>>>>> should
>>>>>>>> be
>>>>>>>> only associated with JSP session scope.  But if I am wrong,
>>>>>>>> could be
>>>>>>>> the problem.
>>>>>>>> Obviously, I have a misunderstanding about either Cayenne
or Tomcat
>>>>>>>> caching
>>>>>>>> or perhaps its a combo of the two.  It appears from my tests
>>>>>>>> the
>>>>>>>> singleton class may be constructed the first time after Tomcat
>>>>>>>> restarted
>>>>>>>> and then remains persistent even across different sessions.
>>>>>>>> Are there any suggestions as to a simple design in which
>>>>>>>> singleton
>>>>>>>> forces
>>>>>>>> re-initialized (i.e. refresh the Cayenne object from the
DBMS data)
>>>>>>>> upon
>>>>>>>> each new session?
>>>>>>>> Thanks,
>>>>>>>> Joe

Lawrence Gerstley, Ph.D.
PSMI Consulting

Cel: 415.694-0844

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message