Local and shared cache can be implemented as separate caches, or as a single 
cache with different regions. But in any event they are guaranteed to store 
keys in namespaces separate from each other. Moreover per-context local caches 
are also separate from any other local cache.

The shared cache is attached to DataDomain:

DataContext dataContext = ..
QueryCache sharedCache = dataContext.getParentDataDomain().getQueryCache();

Andrus


On Aug 4, 2011, at 9:52 PM, Joseph Senecal wrote:

> That most certainly could be the reason. I thought there was only a single 
> cache that a program could have only local caches or a shared cache but not 
> both, and that getQueryCache returned the appropriate cache. Now the behavior 
> makes sense.
> 
> Could you point me towards how to get access to the shared cache?
> 
> Joe
> 
> On Aug 4, 2011, at 11:46 AM, Andrus Adamchik wrote:
> 
>> I think I spotted something here... You are removing the entry from LOCAL 
>> cache of the ObjectContext, while the query is run against SHARED cache. 
>> Could that be the reason?
>> 
>> Andrus
>> 
>> 
>> 
>> On Aug 4, 2011, at 9:34 PM, Joseph Senecal wrote:
>> 
>>> Yes, the item is committed. Stepping though the code that did the lookup I 
>>> can see that it is not going to the database at all (all SQL is being 
>>> logged).
>>> 
>>> The idea is that once an item exists it is unlikely to change. But items 
>>> that don't exist are very likely to be added. So in the routine that 
>>> fetches the item, it removes the entry from the cache if nothing was 
>>> fetched from the database. That way I don't need to flush the entire cache 
>>> when only this one query needs to have it's results flushed.
>>> 
>>> I did try flushing the entire cache group, but that didn't help either.
>>> 
>>> I've just managed to get a workaround working, where I keep track of the 
>>> keys that didn't fetch result and set the query to refresh in that case. 
>>> That is working, though I had to switch from a NamedQuery to a SelectQuery 
>>> to be able to make that change dynamically. I left the code to try deleting 
>>> the entry in place. Here's the code I ended up with:
>>>     private static Set<String> missingPartMap = new HashSet<String>();
>>> 
>>>     static public BOMModule moduleWithPartNum(String value, ObjectContext 
>>> context) {
>>>             if (value == null) {
>>>                     return null;
>>>             }
>>> 
>>>             Expression expression = 
>>> ExpressionFactory.matchExp(PART_NUM_PROPERTY, value);
>>>             SelectQuery query = new SelectQuery(BOMModule.class, 
>>> expression);
>>>             query.setCacheGroups("BOMModule");
>>>             boolean missingPart = missingPartMap.contains(value);
>>>             query.setCacheStrategy(missingPart ? 
>>> QueryCacheStrategy.SHARED_CACHE_REFRESH : QueryCacheStrategy.SHARED_CACHE);
>>>             BOMModule part = null;
>>>             try {
>>>                     List<BOMModule> list = fetchBOMModuleList(context, 
>>> query);
>>>                     if (list.size() > 0) {
>>>                             part = list.get(0);
>>>                             if (missingPart) missingPartMap.remove(value);
>>>                     } else {
>>>                             if (!missingPart) missingPartMap.add(value);
>>>                     }
>>>             } finally {
>>>                     if (part == null && context instanceof DataContext) {
>>>                             // No match or multiple match. Either way 
>>> remove this from the cache so that we'll see when it's fixed
>>>                             DataContext dataContext = (DataContext) context;
>>>                             String key = 
>>> query.getMetaData(dataContext.getEntityResolver()).getCacheKey();
>>>                             dataContext.getQueryCache().remove(key);
>>>                             assert 
>>> (dataContext.getQueryCache().get(query.getMetaData(dataContext.getEntityResolver()))
>>>  == null);
>>>                     }
>>>             }
>>>             return part;
>>>     }
>>> 
>>> And here the generated fetchBOMModuleList routine from the super class: 
>>>  @SuppressWarnings("unchecked")
>>>  public static List<BOMModule> fetchBOMModuleList(ObjectContext context, 
>>> Query query) {
>>>      return (List<BOMModule>) context.performQuery(query);
>>>  }
>>> 
>>> That's just a generated helper method to hide the suppress warnings.
>>> 
>>> Sorry for having all these strange problems where things don't work for me 
>>> but work for everyone else :-/  And thanks for your prompt replies!
>>> 
>>> Joe
>>> 
>>> On Aug 4, 2011, at 11:20 AM, Andrus Adamchik wrote:
>>> 
>>>>> But when I make the same query (now that the code has created the item), 
>>>>> I'm getting an empty result again. 
>>>> 
>>>> Is that item committed? Queries are run against the DB and won't see items 
>>>> that haven't been committed.
>>>> 
>>>> Also in general an app would invalidate cache by cache group. This way you 
>>>> won't need to know the cache key of a query, and can invalidate multiple 
>>>> queries at once.
>>>> 
>>>> Andrus
>>>> 
>>>> 
>>>> On Aug 4, 2011, at 5:10 AM, Joseph Senecal wrote:
>>>> 
>>>>> Using Cayenne 3.1M2
>>>>> 
>>>>> When a cached query for a single record returns no entry, I'd like to 
>>>>> remove that single result from the cache. Either the code will be 
>>>>> creating the record, or it will be manually added and I want the code to 
>>>>> notice when it is. It looks like this should be possible using this code:
>>>>>                           DataContext dataContext = (DataContext) context;
>>>>>                           String key = 
>>>>> query.getMetaData(dataContext.getEntityResolver()).getCacheKey();
>>>>>                           dataContext.getQueryCache().remove(key);
>>>>>                           assert 
>>>>> (dataContext.getQueryCache().get(query.getMetaData(dataContext.getEntityResolver()))
>>>>>  == null);
>>>>> 
>>>>> 
>>>>> And when I run the code the assert confirms that the entry has been 
>>>>> removed.
>>>>> 
>>>>> But when I make the same query (now that the code has created the item), 
>>>>> I'm getting an empty result again. 
>>>>> 
>>>>> I'd prefer not to have to flush the entire table cache whenever I create 
>>>>> a new entry, is this possible?
>>>>> 
>>>>> Joe
>>>> 
>>> 
>>> 
>> 
> 
> 

Reply via email to