0
votes

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

3

3 Answers

0
votes
  1. 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.

  2. 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

0
votes

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.

0
votes

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.

if the user is updated the Querycache will become wrong for this user

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.

I want it to be updated when i update the user

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!