PlayFramework 缓存中的对象似乎是原始对象?

Objects from cache in PlayFramework seem to be the original objects?

关于缓存的另一个 PlayFramework 2.x(具体为 2.5)相关问题。 Play 使用 EhCache,但我认为这是一个 Play 问题,而不是 EhCache 问题 - 但我可能错了。

所以我从缓存中获取对象。在此示例中,我从数据库中获取菜单项,然后突出显示当前菜单项。这是代码:

List<Menu> menuitems = cache.getOrElse("menu", () -> getMenuitemsFromDatabase(), DURATION_14_DAYS);
for (Menu menuitem : menuitems) {
    if (menuitem.getUrl().equals(request.uri())) {
        menuitem.setHighlighted(true);
        break;
    }
}

问题是,我总是从缓存中获取相同的对象。对于相同的对象,我实际上是指内存中的相同对象。我猜它存储在内存中的某个 hashmap 中,我每次都获取相同的条目。

这意味着,当我浏览到两个网站时,当前和上一个菜单项会突出显示。显然,如果我浏览更多网站,情况会变得更糟。

我期望(并且需要)的是菜单项列表的副本。如果我用 Redis 替换 EhCache,我总是得到副本(这是有道理的,因为 redis 服务器是另一台机器)。

那么,我如何告诉 Play 只获取缓存对象的副本。我真的不想手动复制所有这些对象。如果没有内置的 Play 解决方案,那么通用的方法是什么? 显然,缓存中的所有对象都是可序列化的,所以我想可以很容易地复制这些对象。

谢谢, 舒贝

不确定这里使用的是哪个版本的 ehcache,因此如何解决这个问题可能会有所不同...但是如果不需要,Ehcache 确实会不会 复制对象。仅当还需要序列化时才需要它(例如您的 redis 用例)。但是只要条目保留在 JVM 的堆上,您就会得到相同的对象。

如何最好地解决这个问题?好吧,这取决于:您可以在 ehcache (2.x / 3.x) 的缓存级别强制执行 "copy-on-read/write" 语义;但如果我是你,我会考虑其他解决方案......你正在为缓存访问引入不必要的延迟,因为这个......但我不确定你如何最好地解决在这个非常具体用例

无论如何,模仿 redis(脱离 VM)copy-on-read/write 语义可能是最简单的,但性能也可能是最差的。