0

我将 Hibernate 与 Ehcache 一起使用(不认为这很重要)。当用户登录时,我通过他的电子邮件识别他,并将他的电子邮件用于所有后续呼叫。现在,由于电子邮件不是我的“休眠 ID”(我用 注释的那个@Id),我必须使用查询加载它,因此将其存储在查询缓存中。但是,当用户注销时,我无法明确地将他从缓存中逐出,因为他存储在与其他已登录用户共享的区域内。

我的问题是:我可以将用户加载到二级缓存中(从而使驱逐更容易),而无需使用该session().get(user)方法再次访问数据库吗?这里还有一点,如果用户被更新,查询缓存对于这个用户来说是错误的。我希望在更新用户时更新它

4

3 回答 3

0
  1. 为什么要将用户从缓存中逐出?适当地配置缓存,它会在一段时间后不再使用时将其从缓存中删除。

  2. 如果您通过休眠更新用户,二级缓存应该会看到并处理它。

听起来你想阅读 Hibernate 中的缓存:http ://www.javalobby.org/java/forums/t48846.html

于 2011-10-30T11:05:32.317 回答
0

第一个问题:为什么要在用户注销时从查询缓存中删除用户?我无法想象你的架构为什么需要这样。缓存应该是透明的,并且 EhCache 可以在不再需要或不适合缓存时轻松删除用户。

如果用户更新,则该用户的 Querycache 将变为错误

不,它不会,至少如果更新是通过 Hibernate 进行的。你知道查询缓存是如何工作的吗?在您的情况下,它存储电子邮件->用户 ID映射。当通过电子邮件查询时, Hibernate 将首先找到与该电子邮件关联的用户 id ,然后通过 id 查找用户。如果它存在于二级缓存中,则从那里加载。否则 Hibernate 通过 id 透明地加载用户。不过,它仍然比通过电子邮件查询要好。

也就是说,如果您更新用​​户,Hibernate 将自动更新/驱逐 L2 缓存并为所有涉及用户的查询更新查询缓存。它只是工作。

我希望在更新用户时更新它

你什么意思?您将遇到的唯一陈旧数据是存储在 L1 缓存中的用户实例,L2 和查询缓存会无缝更新。

另请参阅:使用 Hibernate + Spring 进行缓存 - 一些问题!

于 2011-10-30T11:05:57.290 回答
0

你让它变得比必要的更难。每次使用相同的参数执行查询时,请使用查询缓存来避免访问数据库。如果用户注销,带有这些特定参数的查询随后将不会执行太多,缓存最终将根据其驱逐策略(LRU、超时等)从缓存中驱逐这个特定查询。缓存应该是透明的,你不应该驱逐任何东西。

如果您使用 ID 来引用用户而不是使用他的电子邮件地址,则可以完全避免此用例的查询缓存。ID 用于:唯一地引用一个实体,并且能够使用 session.get 和 session.load 来加载用户。使用电子邮件登录很好。登录后,应用程序应该使用他的 ID 来指代用户,而不是他的电子邮件。

关于最后一点:如果更新用户,Hibernate 会自动使缓存的结果无效。即使没有,查询缓存也只存储返回的实体的 ID。实体的状态是从实体缓存中加载的,实体缓存在更新实体时会失效(或更新)。

于 2011-10-30T11:08:39.203 回答