Issue
I'm using JPA to load and persist entities in my Java EE-based web application. Hibernate is used as an implementation of JPA, but I don't use Hibernate-specific features and only work with pure JPA.
Here is some DAO class, notice getOrders
method:
class OrderDao { EntityManager em; List getOrders(Long customerId) { Query q = em.createQuery( "SELECT o FROM Order o WHERE o.customerId = :customerId"); q.setParameter("customerId", customerId); return q.getResultList(); } }
Method is pretty simple but it has a big drawback. Each time the method is called following actions are performed somewhere within JPA implementation:
- JPQL expression is parsed and compiled to SQL.
- Either Statement or PreparedStatement instance is created and initialized.
- Statement instance is filled with parameters and executed.
I believe that steps 1 and 2 of above should be implemented once per application lifetime. But how to make it? In other words, I need that Query instances to be cached.
Of course I can implement such a cache on my side. But wait, I am using modern powerful ORM's! Didn't they already made this for me?
Notice that I'm not mentioning something like Hibernate query cache which caches result of queries. Here I'd like to execute my queries a bit more quickly.
Solution
There is a query plan cache in Hibernate. So the HQL is not parsed every time the DAO is called (so #1 really occurs only once in your application life-time). It's QueryPlanCache. It's not heavily documented, as it "just works". But you can find more info here.
Answered By - Thierry-Dimitri Roy
Answer Checked By - Pedro (JavaFixing Volunteer)