i'm working around spring 3.1 annotation cache with ehcache as a cache implement.
a method with return value like this
@Cacheable("cache")
public MyObject getObj(Object param);
i got a myobject return value for the first time,and it's editable. ehcache can do something for that by setting "copyOnRead" or "copyOnWrite". it will force serialize object on read/write. but at the first time spring will not get value from cache,it always return by method itself.
is there some way to get a readonly return value?
I had the same problem with the spring cache. I didn't want to receive the same java objects from the cache.
In my case i want to cache big java objects with many fields and so on. So it is very painful to copy all the data classes with deep copy. I read the article about copy java objects with serialization.
http://www.javaworld.com/article/2077578/learn-java/java-tip-76--an-alternative-to-the-deep-copy-technique.html
This brought me to the idea to cache only the serialized data. Every time a object is read from the cache it is deserialized.
For the serialization i used apache commons helper methods
It depends on the spring configuration if the call to readCachedUserQuestion could be in the same class or not. Per default only extern calls to a method are cached.
You could write your own aspect that always creates a copy of the returned value, which would make you independent of some Ehcache settings.
At first, a marker annotation like
@CopyReturnValue
would be nice for expressing the pointcut:Now, the aspect can use this annotation for the pointcut expression:
Finally, add the annotation to your method:
For the
CopyReturnValueAspect
I useBeanUtils
to create a copy of the returned value - just as an example. For further information on that topic, you might want to look at How to copy properties from one Java bean to another?Oh, don't forget to enable @AspectJ support in you Spring configuration if you haven't already: