Spring caching list and updating it's values

6.2k views Asked by At

I'm creating Spring application which saves in Postgres database GPS positions of vehicles. Vehicles send their position every minute. Every vehicle is identified by some ID (String). There is REST endpoint to get all current positions. I would like to cache all current GPS positions to make it faster to get without requesting database.

I tried to use:

@Cacheable(key = "'all'")
List<Position> getAllVehiclePositions();

and it works but problem is when some vehicle sends new position, then I have no possibility to update list in cache so I have to

@CacheEvict(key = "'all'")

which doesn't make any sense because cache is being still evicted.

I've read about it e.g. https://jira.spring.io/browse/SPR-12036 but there is no solution (only not to use cache).

I thought about creating ConcurrentHashMap where key would be vehicle ID so I could easily update it and I could simply use streams to convert List to Map.

What should I do? What's the best solution?

2

There are 2 answers

0
cjungel On BEST ANSWER

I would consider 2 options depending how up to date does the response need to be.

Option 1: @Cacheable + TTL

If you don't need absolutely up to date responses you could simply use the @Cacheable annotation and configure the cache for a TTL of 30 seconds, 1 minute or whatever makes sense for your application. This has the advantage of not having to worry about cache population and eviction in your business code at the expense of serving potentially outdated data (but you control how outdated).

Option 2: ConcurrentHashMap + custom cache update logic

If you always need the latest data then I would suggest you use a ConcurrentHashMap making sure that you keep it up to date with the database. This has the advantage of having the latest data available at the cost of having to implement cache population and eviction.

1
Selim Ok On

I think you can use @CachePut annotation. See: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-annotations-put

what you can do besides the normal update method create a second method to update your list of all position like this:

public Position updatePosition(...){
    ...
    updateAllPositions(...) 
}

@CachePut(key="'all'") 
public List<Position> updateAllPositions(...){
    ... 
}