Closed GoogleCodeExporter closed 9 years ago
Adding a keyGeneratorClass is a good idea. How do you want to use it with
ReadThrough* annotations? Could you show some examples how intercepted method
should work with keyGeneratorClass and ReadThrough*?
Original comment by ragno...@gmail.com
on 18 Mar 2013 at 10:06
This is my current code where I added a generateCacheKey method on
PermittedEntity and marked it with @CacheKeyMethod
@ReadThroughSingleCache(namespace = RE_CACHE_NS,expiration = 36000)
public Set<Group> getRepresentativeEntities(@ParameterValueKeyProvider(order =
1) PermittedEntity entity, @ParameterValueKeyProvider(order = 2) boolean
inherit){
...
}
I prefer not coupling PermittedEntity with SSM and not adding this kind of code
to many of my entities. I'd like to do something like that:
@ReadThroughSingleCache(namespace = RE_CACHE_NS,expiration = 36000,keyGenerator
= PermittedEntityKeyGenerator.class)
public Set<Group> getRepresentativeEntities(@ParameterValueKeyProvider(order =
1) PermittedEntity entity, @ParameterValueKeyProvider(order = 2) boolean
inherit)
public class PermittedEntityKeyGenerator{
//where key providers are the arguments marked with @ParameterValueKeyProvider
@CacheKeyMethod
public String generateCacheKey(Object[] keyProviders){
...
}
}
or generateCacheKey could just have the same signature as getCacheKey in
SingleReadCacheAdvice:
String getCacheKey(final AnnotationData data, final Object[] args, final String
methodDesc)
and if there is a keyGenerator use it, else do it as before.
Original comment by shalom...@gmail.com
on 19 Mar 2013 at 8:55
As I understand you don't want to use keyGenerator on cached class/entity but
on some other class used as a ParameterValueKeyProvider, do you?
Original comment by ragno...@gmail.com
on 19 Mar 2013 at 6:14
Currently it is possible to create custom
com.google.code.ssm.aop.support.CacheKeyBuilder and use it instead of the
default one (CacheKeyBuilderImpl).
In your case you can extend CacheKeyBuilderImpl and if the methodDesc matches
to some pattern (or one of the args is of given type) instead of default logic
execute own code to created cache key.
Does it suit you?
Original comment by ragno...@gmail.com
on 19 Mar 2013 at 6:23
Thanks. CacheKeyBuilder is a good option and I did implement it and removed
CacheKeyMethod from my entities.IMO its a better option.
still, it brings worries with it, needs maintenance and to preserve
compatibility with future SSM versions. where supplying a hook on a per method
basis is simpler to implement and is not coupled with SSM.
In order to replace CacheKeyBuilder I also had to override cacheBase bean
imported from your simplesm-context.xml and I'm relying on spring to override
it.
anyway, for references to others, this is my implementation, I did copy paste
your private buildCacheKey method and used DefaultKeyProvider in my code.
@Override
public String getCacheKey(AnnotationData data, Object[] args, String methodDesc) throws Exception
{
final Object[] keysObjects = Utils.getMethodArgs(data.getKeyIndexes(), args, methodDesc);
if (keysObjects == null || keysObjects.length < 1) {
throw new InvalidParameterException("At least one key provider object needed for cached method.");
}
if (contains(SdAbstractEntity.class, keysObjects) || contains(ADPojoBase.class, keysObjects)){
return getSpecialCacheKey(data, keysObjects);
}else{
return super.getCacheKey(data, args, methodDesc);
}
}
private String getSpecialCacheKey(AnnotationData data, Object[] keysObjects)
{
List<String> keyParts = new ArrayList<String>();
for (Object keyProvider: keysObjects){
if (SdPermittedEntity.class.isAssignableFrom(keyProvider.getClass())){
keyParts.add(getSdPermittedEntityKey((SdPermittedEntity)keyProvider));
}else if (SdAbstractEntity.class.isAssignableFrom(keyProvider.getClass())){
keyParts.add(getSdAbstractEntityKey((SdAbstractEntity) keyProvider));
}else if (ADPojoBase.class.isAssignableFrom(keyProvider.getClass())){
keyParts.add(getADPojoBaseKey((ADPojoBase)keyProvider));
}else{
keyParts.add(defaultKeyProvider.generateKey(keyProvider));
}
}
final String[] objectKeys = keyParts.toArray(new String[keyParts.size()]);
return buildCacheKey(objectKeys, data.getNamespace());
}
Thank you.
Original comment by shalom...@gmail.com
on 20 Mar 2013 at 12:37
Well , after noticing that I don't support multi cache keys in my
CacheKeyBuilder I realized that I can replace only the DefaultKeyProvider to
support my special keys instead of replacing CacheKeyBuilder, and its good for
all cache aspects. so now I use CacheKeyBuilderImpl with my own KeyProvider, I
had to override only generateKey.
this is now very satisfying for me.
@Override
public String generateKey(Object keyObject)
{
if (SdPermittedEntity.class.isAssignableFrom(keyObject.getClass()))
{
keyObject = getSdPermittedEntityKey((SdPermittedEntity) keyObject);
} else if (SdAbstractEntity.class.isAssignableFrom(keyObject.getClass()))
{
keyObject = getSdAbstractEntityKey((SdAbstractEntity) keyObject);
} else if (ADPojoBase.class.isAssignableFrom(keyObject.getClass()))
{
keyObject = getADPojoBaseKey((ADPojoBase) keyObject);
}
return super.generateKey(keyObject);
}
Original comment by shalom...@gmail.com
on 20 Mar 2013 at 6:20
So may I close the issue or do you still would like to see keyGenerator in next
SSM release?
Original comment by ragno...@gmail.com
on 20 Mar 2013 at 6:30
Sure, you can close. I'm doing fine as it is now. Thanks for your help.
Original comment by shalom...@gmail.com
on 20 Mar 2013 at 6:39
No problem.
Original comment by ragno...@gmail.com
on 20 Mar 2013 at 6:42
Original issue reported on code.google.com by
shalom...@gmail.com
on 18 Mar 2013 at 2:35