What if I have a query that gets called multiple times in a single thread, and I just want to cache that query (and its result) for that thread (or for that session since I'm using one session per thread), how can I do that ?
Note: My 2nd level cache is turned on but it's used mostly for session.get(...). But I do not want to use it for my query cache because I only need it to live for the duration of my thread ( / session ).
Thanks
The bottom line here is: you can either manually cache your query results or you can ask Hibernate to do it. While it generally makes little sense to restrict your query cache lifetime to that of session, it can be done using the following approach:
2) Dedicate a specific region for query in question and mark it as cacheable:
Query query = ...;
query.setCacheable(true).setCacheRegion("MY_SPECIAL_QUERY");
3) Evict your query from cache at the end of the session (if you're REALLY sure that's what you want to do):
SessionFactory sessionFactory = ...;
sessionFactory.evictQueries("MY_SPECIAL_QUERY");
Query caching cannot be applied to the session cache. This makes sense, since generally all operations against a session are done by one piece of code, which should just be able to remember the results itself.
You say you don't want to enable 2nd-level query caching, but what would be the harm in doing so? You'd get your desired results.
I don't know of any such feature for Hibernate.
But this seem to be a very limited and manageable context. I would try to do that is the code. Various ways seem possible at first sight:
- If your code is well known, the complexity is manageable. Suppose you have a code A, that calls codes B and C, both of them need the query. You can run the query once in A, as pass the result to B and C. Maybe you already have a context object that you send to B and C? That would be simple, elegant, meaningfull...
Suppose the opposite, that your code is a real mess, and you can't pass a context around. You could have a ThreadLocal variable that contains the result. If not set inside the current thread, call it and store it. Otherwise, just retrieve it.
Note that, in the second case, you would have to take care of cleaning the ThreadLocal when going out.
Between these opposites, solutions are possible, one of them is probably better than others...
来源:https://stackoverflow.com/questions/1432705/how-to-enable-hibernate-query-cache-on-a-session-level-only