My Hibernate/JPA model has this entity classes
@Entity
public class Student {
@ManyToOne(optional = false)
@JoinColumn(name = "course_id")
private Course course;
// other properties, getters, setters, etc. omitted
}
This student-course relationship is unidirectional i.e. there is no reference to the Student entity in Course.
The default fetch type for @ManyToOne is eager, so the annotation above is the same as @ManyToOne(optional = false, fetch = FetchType.EAGER).
So whenever I execute a query that fetches students, the associated courses are also fetched, e.g.
select s
from Student s
where s.name = 'Bob'
However, although the courses are fetched at the same time, a separate query is issued to fetch them. If I want to fetch the student(s) and course(s) in a single query, I need to explicitly include a join fetch in my JPQL query, e.g.
select s
from Student s
join fetch s.course
where s.name = 'Bob'
As it's tedious and error prone to apply this update to all my student queries, is it possible to make join-fetching the default behaviour? In other words, to have the first query (without an explicit join) behave like the second query (join-fetch course by default)?
There is no such possibility, I'm afraid. The
joinclause have semantics that may affect the query, so it would be dangerous to add a default clause. Consider an example like yours, but where thecourserelation is optional. Ajoin fetch s.coursewould limit the result to students that have a course reference (it is an inner join after all), and students without courses (or with invalid course references) would simply be invisible to the query.The JPA 3.1 specification states that
Unless you prove that there are considerable performance advantages of fetching it all in one query, I would recommend settling with the default behaviour...