JUNTE-SE
Ao usar JOINcontra associações de uma entidade, o JPA gerará uma JOIN entre as tabelas da entidade pai e da entidade filha na instrução SQL gerada.
Então, tomando o seu exemplo, ao executar esta consulta JPQL:
FROM Employee emp
JOIN emp.department dep
O Hibernate irá gerar a seguinte instrução SQL:
SELECT emp.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id
Observe que a SELECTcláusula SQL contém apenas as employeecolunas da tabela, e não departmentas. Para buscar as departmentcolunas da tabela, precisamos usar em JOIN FETCHvez de JOIN.
JUNTE-SE À PESQUISA
Portanto, em comparação com JOIN, o JOIN FETCHpermite projetar as colunas da tabela de junção na SELECTcláusula da instrução SQL gerada.
Portanto, no seu exemplo, ao executar esta consulta JPQL:
FROM Employee emp
JOIN FETCH emp.department dep
O Hibernate irá gerar a seguinte instrução SQL:
SELECT emp.*, dept.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id
Observe que, desta vez, as departmentcolunas da tabela também são selecionadas, não apenas as associadas à entidade listada na FROMcláusula JPQL.
Além disso, JOIN FETCHé uma ótima maneira de abordar a questão LazyInitializationExceptionao usar o Hibernate, pois você pode inicializar associações de entidades usando a FetchType.LAZYestratégia de busca junto com a entidade principal que você está buscando.