-
Notifications
You must be signed in to change notification settings - Fork 5
Key Transformation
###Why?
Sometimes you need to avoid saving keys in the cache directly, f.e. you want to use primary key as a cache key instead of DB entity, but you still need the object itself to calculate the value.
###How?
In this case MxCache support key transformation.
Annotate key argument with a special annotation in addition to @Cached:
@Transform(owner = class.that.contains.transforming.Method.class, method = "methodName")Before saving the record in the cache, the corresponding key value field will be replaced by the result of given method invocation, passing in the initial value.
It is allowed to omit the name of the method , in this case, only the method that takes one parameter will be used as the transformer (an exception will be thrown, if such method does not exist ) .
You can also specify a class that contains a transformer, in this case method key with the corresponding name will be used as the transformer.
For example , the cache will ignore such key register :
@Cached
public Value test(@Transform(method = "toLowerCase") String x) { ... }Not only static methods can act as transformers. Non-static copies of the transformers will be obtained through MxCache instance provider.
Long annotation @Transform can be replaced by a simple user annotation.
To do this, create your own data, and put out @Transform in front.
Now this short annotation stands for the long @Transform annotation that you annotated it with.
Example:
@Cached
public Value method(@Transform(owner = HereIsAVeryLongClassName.class, method = "ohDoSomeComputationsWithMyKeyAndReturnMeResult") Key1 k1,
@Transform(owner = HereIsAVeryLongClassName.class, method = "ohDoSomeComputationsWithMyKeyAndReturnMeResult") Key2 k2,
@Transform(owner = HereIsAVeryLongClassName.class, method = "ohDoSomeComputationsWithMyKeyAndReturnMeResult") Key3 k3);can be replaced with
@Transform(owner = HereIsAVeryLongClassName.class, method = "ohDoSomeComputationsWithMyKeyAndReturnMeResult")
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
// we want to avoid improper usage of this annotation
@Target(ElementType.PARAMETER)
public @interface LongTransform {}
@Cached
public Value method(@LongTransform Key1 k1,
@LongTransform Key2 k2,
@LongTransform Key3 k3);Your annotation must be visible at runtime! Ensure that it has proper @Retention (RetentionPolicy.RUNTIME)!!!
###Standard annotations
In mxcache there is a standard set of transforming annotations:
-
@Ignore- makes mxcache ignore options when searching in the cache. Custom strategies must be adapted to work with@WeakKeyand@SoftKeyannotations! -
@WeakKey- makes mxcache use Weak-references to store keys. -
@SoftKey- makes mxcache use Soft-references to store keys. Note: the later two works properly with standard caching strategies. Third-party strategies may require a modification in order to support it.
###More examples
To use a string representation of a key as storage key:
@Cached
public String someCachedMethod(@Transform(method = "toString") Object key);To use id of an entity and name instead of entity itself, the session will not be included in the key:
@Cached
public String findSubobject(@Transform(method = "getId") SomeEntity entity, String name, @Ignore Session session);String representation of id will be used as a key
@Cached
public String findEntity(@Transform(owner = Long.class, method = "toString") long id); Method Key getKey(SomeObject) will be as the transformer:
class X {
static Key getKey(SomeObject o) {...}
}
@Cached
public String findEntity(@Transform(owner = X.class) SomeObject o);