Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

caching - How can we use spring boot cache abstraction to update a list in cache based on update (add, update, delete) operations of single elements?

I got a rather common scenario. I have the model, repository, and service classes for an entity. I want to use caching on the service layer to cache operations like findAll, findById, add, update, and delete.

The findAll operation is likely to be called from many other services. Thus caching a list of entities is important. However, there can be frequent calls to add operations to add new entities; update and delete calls will not be that frequent. Whenever any of these update operations is called, the cache for the list becomes obsolete.

My question is if there is a way to manipulate the list in the cache to update it in place? Or can we evict only the list cache on any of these update operation calls? Or most importantly: what should have been the best practice to follow in such a scenario?

Thanks.

@Service
@CacheConfig(cacheNames = {"bovines"})
public class BovineService implements CrudListener<Bovine> {
    private final BovineRepository bovineRepository;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public BovineService(BovineRepository bovineRepository) {
        this.bovineRepository = bovineRepository;
    }

    @Override
    @Cacheable
    public List<Bovine> findAll() {
        logger.info("Finding all {}(s)", this.getClass().getName());
        List<Bovine> bovines = null;
        try {
            bovines = bovineRepository.findAll();
            logger.info("Found {} {}(s)", bovines.size(), this.getClass().getName());
        } catch (Exception e) {
            logger.warn("Failed to find all {}", this.getClass().getName());
            logger.warn(Arrays.toString(e.getStackTrace()));
        }
        return bovines;
    }

    @Override
    @CacheEvict(allEntries = true)
    @CachePut(key = "#bovine.id")
    public Bovine add(Bovine bovine) {
        logger.info("Saving {}", this.getClass().getName());
        Bovine savedBovine = null;
        try {
            savedBovine = bovineRepository.save(bovine);
            logger.info("Saved {} with ID {}", this.getClass().getName(), savedBovine.getId());
        } catch (Exception e) {
            logger.warn("Failed to add {} with ID {}", this.getClass().getName(), bovine.getId());
            logger.warn(Arrays.toString(e.getStackTrace()));
        }
        return savedBovine;
    }

    @Cacheable(key = "#id")
    public Optional<Bovine> findById(String id) {
        logger.info("Finding {} by ID {}", this.getClass().getName(), id);
        Optional<Bovine> optionalBovine = null;
        try {
            optionalBovine = bovineRepository.findById(id);
            if (optionalBovine.isPresent())
                logger.info("Found {} with ID {}", this.getClass().getName(), id);
            else logger.info("No {} with ID {} exists", this.getClass().getName(), id);
        } catch (Exception e) {
            logger.warn("Failed to find {} with ID {}", this.getClass().getName(), id);
            logger.warn(Arrays.toString(e.getStackTrace()));
        }
        return optionalBovine;
    }

    @Override
    @CachePut(key = "#bovine.id")
    @CacheEvict(allEntries = true)
    public Bovine update(Bovine bovine) {
        logger.info("Updating {}", this.getClass().getName());
        Bovine updatedBovine = null;
        try {
            updatedBovine = bovineRepository.save(bovine);
            logger.info("Updated {} with ID {}", this.getClass().getName(), updatedBovine.getId());
        } catch (Exception e) {
            logger.warn("Failed to update {} with ID {}", this.getClass().getName(), bovine.getId());
            logger.warn(Arrays.toString(e.getStackTrace()));
        }
        return updatedBovine;
    }

    @Override
    @CacheEvict(allEntries = true)
    public void delete(Bovine bovine) {
        logger.info("Deleting {} with ID {}", this.getClass().getName(), bovine.getId());
        try {
            bovineRepository.delete(bovine);
            logger.info("Deleted {} with ID {}", this.getClass().getName(), bovine.getId());
        } catch (Exception e) {
            logger.warn("Failed to delete {} with ID {}", this.getClass().getName(), bovine.getId());
            logger.warn(Arrays.toString(e.getStackTrace()));
        }
    }
}
question from:https://stackoverflow.com/questions/65922268/how-can-we-use-spring-boot-cache-abstraction-to-update-a-list-in-cache-based-on

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...