In the last post (see organize your named queries) a nice way to organize named queries has been proposed. The advantages of using named queries in the first place is discussed in the mentioned post, too. Hibernate offers a nice way removing a big disadvantage of named queries or to be more precise of JPQL queries in general, as compared with associations of an entity. Query results are not cached by default, neither in the first level nor in the second level cache. But you may add a query hint in order to advise hibernate to cache the results. Fortunately, like for associations, the query cache does store the ids for resulting entities, so the first and second level cache is requested for the respective objects. If the values are not present in the cache they are retrieved from the underlying resource.
The query hint may be added like this using annotations:
@Entity @Table @NamedQuery(name = "products.getProductsByClientId", query = "SELECT product FROM Product product, IN(product.client) client WHERE client.id = :clientId", hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }) public class Product { // ... }
Using a mapping file like introduced in the post organize your named queries looks like this:
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"> <named-query name="products.getProductsByClientId"> <query> SELECT product FROM Product product, IN(product.client) client WHERE client.id = :clientId </query> <hint name="org.hibernate.cacheable" value="true" /> </named-query> <!-- place more queries here --> </named-query> </entity-mappings>
There may be arbitrary many query hints in the query definition (see schema file of persistence.xml at xsd:complexType name="named-query"
and xsd:complexType name="query-hint"
.
Very nice and helpful article, thx!