주체가 되는 Entity만 조회하여 영속화
데이터는 필요하지 않지만 연관 Entity가 검색 조건에는 필요한 경우에 주로 사용
연관 Entity도 함께 SELECT 하여 모두 영속화
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "team")
@Builder.Default
private List<Member> members = new ArrayList<>();
public void addMember(Member member) {
member.setTeam(this);
members.add(member);
}
}
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
}
Member, Team은 N:1 관계이다.
@Query("SELECT distinct t FROM Team t JOIN t.members")
public List<Team> findAllWithMembersUsingJoin();
Hibernate:
select
distinct team0_.id as id1_1_,
team0_.name as name2_1_
from team team0_
inner join
member members1_
on team0_.id=members1_.team_id
→ Join은 실제 쿼리에 Join을 걸어주기는 하지만 Join 대상에 대한 영속성까지는 관여하지 않는다.
@Query("SELECT distinct t FROM Team t JOIN FETCH t.members")
public List<Team> findAllWithMembersUsingFetchJoin();
Hibernate:
select
distinct team0_.id as id1_1_,
members1_.id as id1_0_1_,
team0_.name as name2_1_,
members1_.age as age2_0_1,
members1_.name as name3_0_1_,
members1_.team_id as team_id4_0_1_,
members1_.id as id1_0_1_
from team team0_
inner join
member members1_
on team0_.id=members1_.team_id
→ 실제 쿼리에 Join을 걸어주고 Join 대상의 내부 컬럼까지 가져온다.
오작동을 미리 방지하기 위해 로직에 꼭 필요한 Entity만을 영속성 컨텍스트에 담아놓고 사용해야 한다.
→ 연관 관계가 있는 Entity가 쿼리 검색 조건에는 필요하지만 실제 데이터는 필요하지 않은 상황에 사용한다.
참고
자바 ORM 표준 JPA 프로그래밍