Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HIbernate Entity Manager: How to cache queries?

I am using the Hibernate 3.5.1 and EntityManager for data persistence (with JPA 2.0 and EHCache 1.5). I can obtain the query by the following code:

EntityManager em;
...
Query query = em.createQuery(...);
...

Now, the problem is that EntityManager's createQuery() method returns javax.persistence.Query which, unlike org.hibernate.Query (returned by the SessionFactory's createQuery() method), does not have the org.hibernate.Query.setCacheable() method.

How am I, then, supposed to cache the queries with EntityManager (or some other part of Hibernate)?

like image 610
eold Avatar asked Aug 25 '10 20:08

eold


People also ask

How do I cache a query in Hibernate?

To use the query cache, you must first activate it using the hibernate. cache. use_query_cache="true" property in the configuration file. By setting this property to true, you make Hibernate create the necessary caches in memory to hold the query and identifier sets.

Does Hibernate cache entities?

As with most other fully-equipped ORM frameworks, Hibernate has the concept of a first-level cache. It's a session scoped cache which ensures that each entity instance is loaded only once in the persistent context. Once the session is closed, the first-level cache is terminated as well.

What is L1 and L2 cache in Hibernate?

L1 Cache is the cache that exists per Hibernate session, and this cache is not shared among threads. This cache makes use of Hibernate's own caching. L2 Cache is a cache that survives beyond a Hibernate session, and can be shared among threads.


1 Answers

You can use the unwrap method to get at the vendor implementation when you want to use vendor specific extensions. e.g.,

org.hibernate.Query hquery = query.unwrap(org.hibernate.Query.class);

Then you can work with the vendor specific interface. Alternately you could just unwrap your EntityManager to a Session before ever creating the query.

If you don't want to have any hibernate imports in your code, you could also do

query.setHint("org.hibernate.cacheable", Boolean.TRUE);

Really up to you which way you'd rather introduce vendor dependence.

I would favor the first as it will fail with an exception if hibernate is removed from your dependencies sending up a big red "Hey you developer changing this, there was a vendor dependence here." Whereas the hint simply does nothing if it's not understood by the provider.

Other persons would rather tolerate having vendor dependent magic strings in code over needing to have a compile time vendor dependence.

like image 122
Affe Avatar answered Nov 03 '22 05:11

Affe