Please help me understand where to use a regular JOIN and where a JOIN FETCH.
For example, if we have these two queries
FROM Employee emp
JOIN emp.department dep
and
FROM Employee emp
JOIN FETCH emp.department dep
Is there any difference between them? If yes, which one to use when?
In this two queries, you are using JOIN to query all employees that have at least one department associated.
But, the difference is: in the first query you are returning only the Employes for the Hibernate. In the second query, you are returning the Employes and all Departments associated.
So, if you use the second query, you will not need to do a new query to hit the database again to see the Departments of each Employee.
You can use the second query when you are sure that you will need the Department of each Employee. If you not need the Department, use the first query.
I recomend read this link if you need to apply some WHERE condition (what you probably will need): How to properly express JPQL "join fetch" with "where" clause as JPA 2 CriteriaQuery?
Update
If you don't use
fetch
and the Departments continue to be returned, is because your mapping between Employee and Department (a@OneToMany
) are setted withFetchType.EAGER
. In this case, any HQL (withfetch
or not) query withFROM Employee
will bring all Departments. Remember that all mapping *ToOne (@ManyToOne
and@OneToOne
) are EAGER by default.If you have @oneToOne mapping set to FetchType.LAZY and you use second query(because you need Department objects to be loaded as part of Employee objects) what Hibernate will do is, it will issue queries to fetch Department objects for every individual Employee object it fetches from DB. Later in the code you might access Department objects via Employee to Department single-valued association and Hibernate will not issue any query to fetch Department object for the given Employee. Remember Hibernate still issues queries equal to the number of Employees it has fetched. Hibernate will issue same number of queries in both above queries if you wish to access Department objects of all Employee objects
Dherik : I'm not sure about what you say, when you don't use fetch the result will be of type :
List<Object[ ]>
which means a list of Object tables and not a list of Employee.When you use fetch, there is just one select and the result is the list of Employee
List<Employee>
containing the list of departements. It overrides the lazy declaration of the entity.in this link i mentioned before on the comment, read this part :
this "JOIN FETCH" will have it's effect if you have (fetch = FetchType.LAZY) property for a collection inside entity(example bellow).
And it is only effect the method of "when the query should happen". And you must also know this:
when is the association fetched --> your "FETCH" type
how is it fetched --> Join/select/Subselect/Batch
In your case, FETCH will only have it's effect if you have department as a set inside Employee, something like this in the entity:
when you use
you will get
emp
andemp.dep
. when you didnt use fetch you can still getemp.dep
but hibernate will processing another select to the database to get that set of department.so its just a matter of performance tuning, about you want to get all result(you need it or not) in a single query(eager fetching), or you want to query it latter when you need it(lazy fetching).
Use eager fetching when you need to get small data with one select(one big query). Or use lazy fetching to query what you need latter(many smaller query).
use fetch when :
no large unneeded collection/set inside that entity you about to get
communication from application server to database server too far and need long time
you may need that collection latter when you don't have the access to it(outside of the transactional method/class)