cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joseph Senecal <sene...@apple.com>
Subject Re: How to remove a single entry from cache
Date Thu, 04 Aug 2011 18:52:22 GMT
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
>>> 
>> 
>> 
> 


Mime
View raw message