【问题标题】:CacheEvict on conditional annotation - Spring Caching条件注释上的 CacheEvict - Spring Caching
【发布时间】:2021-01-28 13:56:36
【问题描述】:

我遇到了一个奇怪的情况,我的 @CacheEvict 不起作用。代码如下所示:

@Caching(evict = {
        @CacheEvict(value = CacheConsts.C_CACHE1, keyGenerator = CacheConsts.KG_CACHE1, condition="#someModel != null && #someModel.getSomeProperty() != null"),
        @CacheEvict(value = CacheConsts.C_CACHE2, keyGenerator = CacheConsts.KG_CACHE2, condition="#someModel != null && #someModel.getSomeProperty() != null"),
        @CacheEvict(value = CacheConsts.C_CACHE3, keyGenerator = CacheConsts.KG_CACHE3, condition="#someModel != null && #someModel.getSomeProperty() != null")
})
public boolean addModel(ModelDTO someModel, String tenant);

但是,当我删除条件时它会起作用!!!即使我测试的所有数据都是非空的。

例如:当我删除这个:“#someModel != null && #someModel.getSomeProperty() != null”时,它可以工作。

我正在使用不为空的 ModelDTO 进行测试,并且“someProperty”也不为空。

在我看来,条件会过去,它会驱逐......但事实并非如此。

有什么想法吗?

我的法术是否正确形成?

为什么我的缓存不会在这里驱逐?

这是否与 @Caching 注释或我不知道的 CacheEvict 条件的某些行为有关?

感谢任何帮助或想法的人。

【问题讨论】:

    标签: java spring spring-cache


    【解决方案1】:

    AFAICT,您的 SpEL 表达式condition 似乎是正确的。

    您可能想要验证您的编译器是否将 debug 设置为 true,这是通过“名称”引用方法参数所必需的,因为编译器随后会将变量名称包含在 Java 字节码中。

    您也可以尝试在您的 SpEL 表达式中引用方法参数,一般(出于调试目的),例如:#a0 != null && #a0.someProperty();请参阅docs 中的此部分。

    最后,我写了一个简单的Integration Test模拟你上面的UC。

    测试和支持代码(都包含在引用的测试类中)在某种程度上是相似的。但是,我的代码略有不同,因为我没有使用自定义 KeyGenerator(每个 Cache),因此我不需要包含 Caching 注释(我只是使用了 cacheNames),但这应该是小后果。测试通过!

    希望这会给你更多的想法。

    如有必要,请随意使用我的测试进行实验。

    干杯!

    【讨论】:

    • 谢谢约翰!我会看看。关于编译器中有关调试的评论。我是否正确理解根据编译器设置可能无法正确解释 SpEL?如果我按名称而不是位置引用方法参数,那么根据编译器设置,条件可能不起作用?
    • 没错。我发现这篇简短的文章可能会更好地解释它 (logicbig.com/how-to/java-command/compile-with-debug-info.html)。通常,IDE 和构建工具(例如 Maven 编译器插件:maven.apache.org/plugins/maven-compiler-plugin/…)默认启用此编译器选项。所以,我不完全确定这是你的问题,但需要检查。
    • 例如,如果我将测试类中UserService.process(:User)方法的@Cacheable注解中的condition属性修改为condition = "#user != null && #user.name != null && #nonExistingArgument != null",那么这里的测试会失败(@987654325 @)。也就是说,User ("jonDoe") 永远不会添加到“Admin”、“Users”和“Guests”缓存中。
    • 这意味着如果引用变量(例如nonExistingArgument)没有(SpEL)上下文信息,则SpEL无法解析有关var的任何信息并且条件将失败。
    • 嗯,这很有帮助,而且您知道项目的移动速度有多快,所以我不会回去验证.. 只是要标记它,这样我就不会让它挂起。我很确定这一定是它。如果教程提到这种方式而不是命名的 vars 方式,那就太好了。无论哪种方式,它都是一个很好的答案,谢谢约翰。 +++
    猜你喜欢
    • 2015-05-08
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2018-03-15
    • 2019-07-14
    • 1970-01-01
    • 2012-03-19
    • 2011-03-03
    相关资源
    最近更新 更多