Reputation: 2536
I have a map that stores simple POJOs, the key is the id field of the POJO. From Spring's @CachePut annotation, I expected something like this:
JobModel jm = new JobModel();
cachemap.put(jm.getId(), jm);
Still, it inserts null values to the cache every time. If I disallow null values when I configure the Cache, I get en exception saying null is being inserted.
Code:
@SpringBootApplication
@EnableScheduling
@EnableAutoConfiguration
@EnableCaching
public class Application {
public static void main(String[] args) {
applicationContext = SpringApplication.run(Application.class, args);
}
...
private GuavaCache jobCache() {
return new GuavaCache(CacheNames.CACHE_JOB, CacheBuilder.newBuilder()
.maximumSize(999999)
.build(),
false);// or true, still null values
}
@Bean(name = "cacheManager")
public CacheManager cacheManager() {
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
simpleCacheManager.setCaches(Arrays.asList(
jobCache(),....
));
return simpleCacheManager;
}
And the Dao class, implementing an interface, the Annotations are declared in the Dao's (the class that implements the interface, not in the interface itself)
@CachePut(value = CacheNames.CACHE_JOB,key = "jm.id")
@Transactional
@Override
public void insert(JobModel jm) {...}
I tried jm.id
, jm.getid()
, #a0.getId()
. Still, everytime I get and exception from com.google.common.base.Preconditions.checkNotNull()
(or just a simple null insert). I placed a breakpoint there and I can see that the key is what I expected it to be (a guid, string), but the value is null.
Upvotes: 1
Views: 3486
Reputation: 2512
Also, you can use unless
conditional property on the cache annotations as below. This parameter takes a SpEL expression that is evaluated to either true
or false
. If true
, the method is cached - if not, it behaves as if the method is not cached.
@CachePut(value = CacheNames.CACHE_JOB, key = "jm.id", unless = "#result == null")
@Transactional
@Override
public void insert(JobModel jm) {
return jm;
}
Upvotes: 1
Reputation: 71
Per the spring docs at http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/CachePut.html
it always causes the method to be invoked and its result to be stored in the associated cache.
Your insert method needs to return the value you want cached.
Could be something as simple as:
@CachePut(value = CacheNames.CACHE_JOB,key = "jm.id")
@Transactional
@Override
public JobModel insert(JobModel jm) {
return jm;
}
though this doesn't feel like the best way to design the interaction. You may want to look at moving the annotation to whatever method is constructing the JobModel passed to the insert method or if the JobModel is being read from a database, the method which saves the JobModel to the database may be a good place as well.
Upvotes: 2