Difference JOIN and JOIN FETCH in JPQL
TLDR: The FETCH
keyword tells the entityManager to also fetch the associated entities which are joined eagerly (when this is not already the case).
Lets say we an user entity and userInfo entity. The user entity has a @OneToMany
relationship with userInfo as follows:
import javax.persistence.*;
@Entity
@Table(name= "test_user")
public class User {
// ... user properties id etc
@OneToMany(mappedBy = "user" fetch = FetchType.LAZY)
private List<UserInfo> infoList;
}
And suppose we have the following Queries (this Spring data JPA syntax, however does not matter how JPQL is constructed):
@Query("SELECT user FROM User user JOIN user.infoList info")
public List<User> getUsersJoin();
@Query("SELECT user FROM User user JOIN FETCH user.infoList info")
public List<User> getUsersJoinFetch();
The first Query with only the JOIN
keyword will generate the following SQL:
select u.id, u.email, u.name from test_user u
inner join test_user_data on u.id=test_user_data.user_id;
As you can see it will only fetch data from the test_user table and not from the test_user_data table. This can also be seen in the debugger as follows:
As can be seen we do not have the List<userData>
on our User
object because this is not loaded by default.
Now lets check out the generated SQL for the Query with JOIN FETCH
:
select test_user.id, data.id, test_user.email, test_user.name,
data.data, data.user_id, data.user_id, data.id from test_user test_user
inner join test_user_data data on test_user.id=data.user_id
As can be seen we are now fetching the data from both the test_user and the test_user_data table in the join. This can also be seen in the debugger as follows:
As can be observed we now have access to the List<userData>
within the User
Object.