2012-08-07 61 views
1

我明白多个对象,使用Spring的(3.1)建于CacheManager中使用的Ehcache实现,也有一定的局限性在代理模式下(默认设置)时,按这个帖子:的Ehcache:@CacheEvict上使用批注

Spring 3.1 @Cacheable - method still executed

来考虑一下,我有:

@CacheEvict(value = "tacos", key = "#tacoId", beforeInvocation = true) 
removeTaco(String tacoId) { 
    // Code to remove taco 
} 

removeTacos(Set<String> tacoIds) { 
    for (String tacoId : tacoIds) { 
     removeTaco(tacoId); 
    } 
} 

在这个仓库方法,调用removeTacos(tacoIds)实际上并不会因为从上述限制的缓存集中退出任何东西。我的解决方法是,在上面的服务层上,如果我想要删除多个玉米饼,我会遍历每个taco Id并将其传递到removeTaco(),并且从不使用removeTacos()但是,我不会使用removeTacos()想知道是否有另一种方法来实现这一点。

1)是否有一个SpEL表达式可以传递给关键字,告诉EhCache过期Set中的每个ID?

e.g. @CacheEvict(value = "tacos", key = "#ids.?[*]") // I know this isn't valid, just can't find the expression. 

或者有没有一种方法可以让removeTacos()调用removeTaco并实际过期Cached对象?

回答

1

AFAIK @CacheEvict仅支持删除单个条目(按键)或给定缓存中的所有条目,因此无法立即删除多个条目。如果你想放置,更新或从缓存中删除多个对象(使用注释),你可以切换到memcached看看我的项目Simple Spring Memcached (SSM)

自调用不通过代理,所以解决方案之一是切换到其他模式而不是代理。另一种解决方案(我不推荐它)可能会继续引用服务中的服务(作为自动编写的字段)并使用它来调用removeTaco。

几个月前,我在我的一个项目中遇到过类似的问题。它没有使用Spring Cache,但SSM也需要代理。为了使它工作,我将缓存(注释)从服务移动到DAO(存储库)层。它解决了自调用问题。

2

你可以做两件事情

@CacheEvict(value = "tacos", allEntries = true) 
removeTacos(Set<String> tacoIds) 

这是不那么糟糕的,如果玉米饼是通过调用服务中读取比他们删除

OR

removeTacos(Set<String> tacoIds) { 
    for (String tacoId : tacoIds) { 
     getTacoService().removeTaco(tacoId); 
    } 
} 

多很多(代理)你调用缓存驱逐。

3

的@Caching注释可用于相同类型的诸如@CacheEvict或@CachePut的多个注释结合,这是来自Spring文档的例子

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value="secondary", key="#p0") }) 
public Book importBooks(String deposit, Date date)