The Java Persistence API defines the notion of query hint, which unlike what its name might suggest, it has nothing to do with database query hints. The JPA query hint is a Java Persistence provider customization option.
To pass a query hint, the JPA specification defines the setHint method of the javax.persistence.Query interface.
The very first query hint supported by the JPA standard was the javax.persistence.query.timeout one which defined the number of milliseconds a given JPA query is allowed to run for. Behind the scenes, this hint will instruct Hibernate to call the PreparedStatement.setQueryTimeout method for the associated SQL query that gets executed.
The following example shows you how to set up the javax.persistence.query.timeout JPA query hint.
List<Post> posts = entityManager
"select p " +
"from Post p " +
"where lower(p.title) like lower(:titlePattern)", Post.class)
JPA 2.1 introduced the javax.persistence.fetchgraph query hint as well to provide a query-specific fetch graph that overrides the default fetch plan defined by the entity mapping.
According to the JPA specification, the javax.persistence.fetchgraph query hint should fetch eagerly only the associations that are explicitly specified by the currently provided fetch graph while the remaining association should be fetched lazily.
However, because lazy fetching is a non-mandatory requirement, the Hibernate behavior for the javax.persistence.fetchgraph query hint is different as the associations not specified by the provided fetch graph are fetched according to their entity mapping fetching strategy.
The javax.persistence.fetchgraph query hint can be specified as follows:
JPA 2.1 introduced the javax.persistence.loadgraph query hint as well to provide a query-specific fetch graph that overrides the default fetch plan defined by the entity mapping.
According to the JPA specification, the javax.persistence.loadgraph query hint should fetch eagerly only the associations that are explicitly specified by the currently provided fetch graph while the remaining association should be fetched according to their mapping fetching strategy.
The javax.persistence.loadgraph query hint can be specified as follows:
Unlike JPA, Hibernate offers multiple query hints you can use to customize the execution of a given query. To simplify the way you have to reference a given query hint, Hibernate offers the QueryHints class that looks as follows:
The Hibernate query hints defined by the QueryHints class can be summarized as follows:
Query hint name
Equivalent to setCacheMode method of org.hibernate.query.Query
Equivalent to setCacheRegion method of org.hibernate.query.Query
Equivalent to setCacheable method of org.hibernate.query.Query
Useful for named queries that need to be executed using a JDBC CallableStatement
Equivalent to setComment method of org.hibernate.query.Query
Equivalent to setFetchSizemethod of org.hibernate.query.Query
Equivalent to setFlushMode method of org.hibernate.query.Query
Override the useFollowOnLocking method of org.hibernate.dialect.Dialect
Specify a custom javax.persistence.LockModeType or org.hibernate.LockMode for the current query
Prevent the JPQL or Criteria API DISTINCT keyword from being passed to the SQL query
Equivalent to setReadOnly of org.hibernate.query.Query
Equivalent to setTimeout of org.hibernate.query.Query. The timout value is specified in seconds.
Equivalent to setTimeout of org.hibernate.query.Query. The timout value is specified in milliseconds.
Although you can customize the query execution using the Hibernate-specific query interfaces (e.g. org.hibernate.query.Query), if you’re using the JPA java.persistence.Query interface, you don’t have to unwrap it to get access to the aforementioned query customization options since you can just use the equivalent Hibernate query hint.
Therefore, to fetch the Post entities in read-only mode, you just have to use the org.hibernate.readOnly query hint, as in the following example:
List<Post> posts = entityManager
"select p " +
"from Post p", Post.class)
The hibernate.query.passDistinctThrough query hint is the only way you can prevent the JPQL DISTINCT keyword from being pushed to the associated SQL query.
I'm running an online workshopk on the 14th of May about The Best Way to Fetch Data with Java Persistence and Hibernate.
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
The JPA query hints mechanism allows you to customize the way a given query is executed by Hibernate. For instance, you can specify a timeout threshold or specify that the returned entities should be fetched in read-only mode.