Hibernate、二级缓存和查询缓存
我正在将 Hibernate 与 Ehcache 一起使用(不过,我认为这并不重要).. 当用户登录时,我通过他的电子邮件识别他,并使用他的电子邮件进行所有后续呼叫。 现在,由于电子邮件不是我的“hibernate id”(我用 @Id
注释的那个),我必须使用查询加载它,从而将其存储在查询缓存中。但是,当用户注销时,我无法明确地将他从缓存中逐出,因为他存储在与此后登录的其他用户共享的区域中。
我的问题是:我可以将用户加载到二级缓存中(从而使驱逐更容易),而无需使用 session().get(user)
方法再次访问数据库吗? 这里还有一点,如果用户更新了,查询缓存对于该用户来说将变得错误。我希望当我更新用户时它也更新
I'm using Hibernate with Ehcache (don't think it matters, tho)..
When a user logs in I identify him by his email and I use his email for all subsequent calls.
Now, since email is not my "hibernate id" (the one I annotated with @Id
) I have to to load it with a query and thus, store it in the query cache. However, when the user logs out I can't explicitly evict him from the cache since he is stored within a region that it shares with others users that have logged in since.
My question is: Can I load the user into the 2nd level cache (thus making eviction easier) without going again to the database with the session().get(user)
method?
There is another point here, if the user is updated the query cache will become wrong for this user. I want it to be updated when I update the user
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么要从缓存中驱逐用户?适当配置缓存,一段时间后不再使用时,它会将其从缓存中删除。
如果您通过休眠更新用户,二级缓存应该看到并处理它。
在我看来,您想阅读有关 Hibernate 中的缓存的内容: http://www.javalobby.org/java/forums/t48846.html javalobby.org/java/forums/t48846.html
Why do you want to evict the user from the cache? Configure the cache appropriately and it will remove it from the cache after a little while when it isn't used anymore.
If you update the user through hibernate the 2nd level cache should see that and take care of it.
It sounds to me like you want to read up on caching in Hibernate: http://www.javalobby.org/java/forums/t48846.html
你让事情变得比必要的更加困难。使用查询缓存可以避免每次使用相同参数执行查询时都访问数据库。如果用户注销,带有这些特定参数的查询随后不会执行太多,并且缓存最终将根据其驱逐策略(LRU、超时等)从缓存中驱逐该特定查询。缓存应该是透明的,并且您不必逐出任何内容。
如果您使用 ID 来引用用户而不是使用他的电子邮件地址,则可以在此用例中完全避免查询缓存。 ID 的用途是:唯一地引用一个实体,并且能够使用 session.get 和 session.load 来加载用户。使用电子邮件登录就可以了。登录后,应用程序应该使用他的 ID 来引用用户,而不是他的电子邮件。
关于最后一点:如果更新用户,Hibernate会自动使缓存的结果失效。即使没有,查询缓存也只存储返回实体的 ID。实体的状态是从实体缓存加载的,当实体更新时,实体缓存会失效(或更新)。
You're making it harder than necessary. Use the query cache to avoid hitting the database each time you execute a query with the same arguments. If the user logs out, the query with these specific arguments won't be executed much afterwards, and the cache will eventually evict this particular query from the cache based on its eviction policy (LRU, timeout, etc.). The cache should just be transparent, and you shouldn't have to evict anything.
You could avoid the query cache completely for this use-case if you used the ID to refer to the user instead of using his email address. IDs are used for that: uniquely refer to an entity, and be able to use session.get and session.load to load the user. Using the email for login is fine. After the login, the application should use his ID to refer to the user, and not his email.
Regarding the last point: Hibernate will automatically invalidate the results of the cache if you update the user. And even if it didn't, the query cache only stores the IDs of the entities returned. The state of the entities is loaded from the entity cache, which is invalidated (or updated) when the entity is updated.
第一个问题:为什么要在用户注销时从查询缓存中删除用户?我无法想象为什么你的架构需要这样做。缓存应该是透明的,当不再需要或不适合缓存时,EhCache 可以轻松删除用户。
不,至少如果通过 Hibernate 进行更新,则不会。你知道查询缓存是如何工作的吗?在您的情况下,它存储电子邮件 -> 用户 ID 映射。当通过电子邮件查询时,Hibernate将首先查找与该电子邮件关联的用户ID,然后通过ID查找用户。如果它存在于二级缓存中,则从那里加载。否则,Hibernate 将通过 id 透明地加载用户。不过,它仍然比通过电子邮件查询要好。
也就是说,如果您更新用户,Hibernate 将自动更新/驱逐 L2 缓存并更新涉及用户的所有查询的查询缓存。它就是有效的。
它是什么意思?您将遇到的唯一陈旧数据是存储在 L1 缓存中的用户实例,L2 和查询缓存会无缝更新。
另请参阅:使用 Hibernate + Spring 进行缓存 - 一些问题!
First question: why do you want to remove user from query cache when he logs out? I can't imagine why your architecture requires that. Caching should be transparent and EhCache can easily remove the user when it is no longer needed or does not fit into cache.
No it won't, at least if the update is through Hibernate. Do you know how query cache works? In your case it stores email -> user id mapping. When querying by email Hibernate will first find the user id associated with this e-mail and then lookup user by id. If it exists in 2nd level cache, it is loaded from there. Otherwise Hibernate transparently loads user by id. It is still better than querying by e-mail though.
That being said if you update a user Hibernate will automatically update/evict L2 cache and update query cache for all queries involving users. It just works.
What do you mean? The only stale data you will encounter are user instances stored in L1 cache, L2 and query cache are updated seamlessly.
See also: Caching with Hibernate + Spring - some Questions!