Can the Spring cache framework be used to cache a non-serializable objects? - spring

I have a requirement to cache an object that can't be serialized. I am looking for some methodology to cache these kind of objects via a Wrapper. Can it be done?

The objects you want to cache need not to be serialized, but of course the keys you generate to store your corresponding objects must be serialized.
Caching Example with Spring Annotations and Ehcache
Making things #Cacheable
ehcache-spring-annotations (Using Cacheable)
ehcache-spring-annotations (Frequently Asked Questions)

Related

Is putting #Cacheable or #Cache above the Entity enough for Hibernate to start caching?

Is it enough and Hibernate checks methods automatically that are doing stuff with that entity and updates the cache?
Or #Cacheable, #CachePut, #CacheEvict annotations above methods are mandatory for a working cache.
What is cached depends on the configuration. If you enable selective caching, you need to annotate all entities with #Cacheable that should be cached. For queries, you additionally need to provide a cache hint, but all of that can be read in the official documentation: https://docs.jboss.org/hibernate/orm/5.5/userguide/html_single/Hibernate_User_Guide.html#caching

Spring(boot)-redis caching- does it need repository creation?

I would like to ask a question about the spring cache annotation and repository creation.
I am trying to cache my values in redis using the Spring boot.
(I have a value, if it is not in cache, I need to cache it, if it is in cache, I need to get it from there)
I have seen a couple of tutorials on line, some using the cache annotations and others simulating the cache repository. (maybe they do not exclude each other, this is my question about)
Here are some of the tutorials that I have read:
Cache annotation tips
Caching Data using Redis
Intro to Redis with Spring Boot
Spring Boot Redis cache
Some of the above use the #Cacheable, #CachePut and #CacheEvict annotations:
#CachePut(value = 'user', key = "#id")
#CacheEvict(value = 'user', key = "#id")
and prefix the supposed-to-be-stored class with the following annotation:
#RedisHash("balance")
They also extend the JPA or CrudRepository. The 3rd one one, however, creates its own repository.
My question is:
If I used the above annotations (#Cacheable, #CachePut and #CacheEvict) should I create a repository for the class objects I am interested in storing by extending the CrudRepository?
Or does spring create it automatically when using the above annotation and manage it automatically?
An if you extend the CrudRepository yourself, how would you retrieve the items by key from Redis?
Thanks
No this is not needed. Notice that the third link does not mention caching up front. There are two projects , spring cache with a redis cache provider and spring data redis. The third link is talking about the larger and more general use case. Spring data redis is meant to support redis as a full fledged persistence layer. However you are certainly free to only use redis as a caching layer. In this case you do not need to do anything nor should you besides using the normal annotations

Create cache from object type through annotations

So,
I'm trying to convert our existing caching (ehcache) to ignite cache, and migrating to spring annotations. I'm running into some difficulty making the annotations work the same as our existing caches though - our existing caches are created automagically whenever we cache something of a new class, and the new cache has the same name as the object's class.
All the current cache logic (along with most of the normal CRUD operation logic) is in an abstract class that's extended for all our persistent objects. In researching the spring annotations, though, it seems like I need to define the cache name on the method - which obviously doesn't work for the abstract class, unless I want all our objects to be in the same cache (possible but definitely not ideal). Ideally I'd specify the cache name as "#this.class.toString", but SPEL isn't allowed in the cache name, like it is in the key.
It seems like the only way to resolve the cache dynamically is by creating your own cache resolver, but for some reason IgniteCache doesn't extend springframework Cache, but javax Cache, and the cache resolver has to return the former. So I'm not even clear how Ignite cache works with spring annotations at all?
This seems like a pretty straightforward use case to me, so it seems weird that spring annotations force me to provide an explicit name on the method, when I'd assume most applications of any significant size are abstracting their persistence methods, and I feel like I must have missed some crucial documentation, but I sure can't find it. Is there a way to specify the name of the cache on the concrete implementation, but keep the caching annotation on the abstract methods?
Thanks!
Your question is quite dense and it's not very clear what you're trying to do. What is "your existing caching" for a start? You need some way to flag the places where you actually cache things I guess. I assume you already understood you need to put a cache annotation there.
As for automatically creating the cache, I wouldn't switch to a different caching system and trying to implement that. Try to migrate first to the cache annotations with your existing cache infrastructure and then migrate to ignite.
Let's pretend you do both still. You are right CacheResolver is the way to go and it can adapt to either a regular org.springframework.cache.Cache or a javax.cache.Cache. Once you have a setup that works, I'd do the following:
In your CacheResolver implementation, inject the cache manager that has been configured
Based on the method call, figure out the cache name to use (get the return type of the method, extract the FQN)
Check if the cache manager has such cache. If it does, return that. If it doesn't create a new cache and add it and then return that
If you're using JCacheCacheManager, you can invoke addCache to create a new cache and then wrap the result in JCacheCache to comply with the signature of CacheResolver.
Last note: automatically creating the cache based on the FQN seems a bit fragile to me, especially if you have sub-classes. You need a bit of control on the caches you create and the settings you apply to them (expiration, size, etc).

How do I invalidate a single entry from springmodules method cache?

We are using springmodules method caching (Spring 2.0.7) in combination with ehcache to cache data which is requested often, in order to take load from the database.
E.g. we are caching the method result of public Profile getUserProfile(User u) {...}: when the user updates data in his own profile, it would be nice to invalidate the cached Profile only for this single User directly after the update, so that the changes are reflected in the user interface right away.
Is there a way to achieve this without invalidating the complete cache for this method?
Or is there a better option than springmodules-caching for this use case?
Thanks a lot for any hints.
Or is there a better option than springmodules-caching for this use case?
Use Spring 3.1 has this new cache feature.
How do I invalidate a single entry from springmodules method cache?
By #CacheEvict from Spring 3.1
The Spring Reference for 3.1 has a nice chapter for this: 28.3 Declarative annotation-based caching

Is there a provider agnostic way of getting up to date cache statistics in Spring framework?

Spring provides a useful feature of Cache Abstraction
But what I could not find is a provider agnostic way to get live cache statistics. Essentially I just want to show a list of all the cache names and their corresponding keys with the count of hits, misses, and sizes (in kb) either on a web page or via JMX. I know Ehcache does provide this feature and if I use ehcache API inside the code I can get it (have already used it in the past). But I believe using Ehcache API inside the code takes away the whole notion of the Spring framework's cache abstraction.
The only common, provider-agnostic thing you have is CacheManager interface, which provides the following method:
Collection<String> getCacheNames()
It returns a collection of the caches known by the cache manager.

Resources