๐ŸŒท Spring/๊ฐœ๋…

[Spring][JPA] ์ตœ๋Œ€ํ•œ ์‰ฝ๊ฒŒ ์•Œ์•„๋ณด๋Š” @EntityGraph์˜ ๊ฐœ๋…

hyeong._.ing 2026. 4. 3. 13:25

 

 

 

์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” DB๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
ํ•œ์ชฝ์— @EntityGraph๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.
@EntityGraph์˜ ์—ญํ• ์ด ๋ญ๊ธธ๋ž˜
์—ฐ๊ด€๊ด€๊ณ„ ํ…Œ์ด๋ธ”์— ํ•„์š”ํ• ๊นŒ?

 

 

 

 

 

๋ฏธ๋ฆฌ ์•Œ์•„์•ผํ•  ๊ฐœ๋… ์„ค๋ช…

  • @EntityGraph๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด์„œ, ํ”„๋ก์‹œ(Proxy)์™€ Lazy(์ง€์—ฐ๋กœ๋”ฉ), Eager(์ฆ‰์‹œ๋กœ๋”ฉ)์— ๋Œ€ํ•ด์„œ ์•Œ์•„์•ผํ•œ๋‹ค.
  • ์•„๋งˆ @EntityGraph์˜ ๊ฐœ๋…์ด ๊ถ๊ธˆํ•œ ์ด์œ ๋Š”, ์ฝ”๋“œ์— @ManyToOne๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์ด๋•Œ @ManyToOne์— fetch = FetchType.Lazy๋ฅผ ์„ค์ •ํ•œ ๊ฒฝ์šฐ @EntityGraph๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ด ์กฐํ•ฉ์„ ๋งŽ์ด ์“ด๋‹ค๋Š” ๊ฑธ ์•Œ๊ณ  ์ผ๋‹จ์€ ๋„˜์–ด๊ฐ€์ž. ์™œ ์ด ์กฐํ•ฉ์„ ๋งŽ์ด ์“ฐ๋Š”์ง€ ๋’ค์— ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.
  • JPA๊ฐ€ DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋‹น์žฅ ํ•„์š” ์—†๋Š” ์—ฐ๊ด€ ๋ฐ์ดํ„ฐ๋Š” ์ง„์งœ ๊ฐ์ฒด ๋Œ€์‹  ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด๋‘๋Š”๋ฐ, ์ด๋•Œ ์ด ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ํ”„๋ก์‹œ๋ผ๊ณ  ๋งํ•œ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฉด @ManyToOne(fetch = FetchType.Lazy)๋Š” ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๋ง๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง„์งœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•˜๋ฉด ๊ทธ์ œ์„œ์•ผ ์ง„์งœ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. → ๊ฒŒ์‹œ๊ธ€์—” ์ž‘์„ฑ์ž ์ด๋ฆ„์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ, ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ์‹œ ์ž‘์„ฑ์ž ์ด๋ฆ„์€ ํ”„๋ก์‹œ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ž‘์„ฑ์ž ์ด๋ฆ„์„ ์š”์ฒญํ•˜๋ฉด ๊ทธ๋•Œ์„œ์•ผ ์ง์ ‘ ์ง„์งœ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„์„œ ๋“ค๊ณ ์˜จ๋‹ค.
  • @ManyToOne์˜ ๊ธฐ๋ณธ๊ฐ’์€ Eager์ด๋‹ค. Eager์€ ์›ํ•˜์ง€ ์•Š์•„๋„ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์ฐพ์•„๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 


 

 

 

 

 

@EntityGraph

  • ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ผ๋Š” ์ด๋ฆ„๊ณผ ๊ฐ™์ด, ์—”ํ‹ฐํ‹ฐ ๊ฐ„์˜ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ํƒ€๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค.
  • DB ์ž…์žฅ์—์„œ JOIN์„ ํ•˜๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.
  • JPA ์ž…์žฅ์—์„œ๋Š” ํ”„๋ก์‹œ ๋Œ€์‹  ์ง„์งœ ๊ฐ์ฒด๋ฅผ ํ•œ๊บผ๋ฒˆ์— ์ฑ„์›Œ ๋„ฃ๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.
  • ๋งŒ์•ฝ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์„ค์ •์ด ์•ˆ๋œ ํ…Œ์ด๋ธ”์— ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฒฝ๋กœ ์ž์ฒด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ์ง์ ‘ JOIN ์ฟผ๋ฆฌ๋ฅผ ์งœ๊ฑฐ๋‚˜ ๋”ฐ๋กœ ์กฐํšŒํ•ด์•ผํ•œ๋‹ค.
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฆ‰์‹œ ํ•„์š”ํ•œ ๊ณณ์—์„œ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. 

 

 

 


 

 

 

 

 

EAGER๊ณผ LAZY์˜ ์˜ˆ์‹œ ์ฝ”๋“œ์™€ ๊ฒฐ๊ณผ

- ์˜ˆ์‹œ) 3๊ฐœ์˜ ๊ฒŒ์‹œ๊ธ€์ด ์žˆ๊ณ , ๊ฒŒ์‹œ๊ธ€์—” ์ž‘์„ฑ์ž๊ฐ€ ํฌํ•จ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

  • EAGER
// ์—”ํ‹ฐํ‹ฐ ์„ค์ •
@Entity
public class Post {

    // ์ฆ‰์‹œ๋กœ๋”ฉ
    @ManyToOne(fetch = FetchType.EAGER) 
    private Member member;
}
// Repository (JPQL ์‚ฌ์šฉ ์‹œ)
@Query("select p from Post p")
List<Post> findAllJPQL();
๊ฒŒ์‹œ๊ธ€์„ ๊ฐ€์ ธ์˜ค๋ผ๊ณ  ํ–ˆ์„ ๋•Œ, EAGER๋กœ ์„ค์ •ํ•ด๋‘๋ฉด ์ž‘์„ฑ์ž ์ด๋ฆ„๋„ ๋ฌด์กฐ๊ฑด ํ•จ๊ป˜ ๊ฐ€์ ธ์˜จ๋‹ค.

1) JPA๋Š” @Query("select p from Post p")๋ฅผ ๋ณด๊ณ  SQL์„ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ SQL์€ SELECT * FROM post;๋กœ ํฌ์ŠคํŠธ๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•œ๋‹ค. 

2) DB๋กœ๋ถ€ํ„ฐ ๊ฒŒ์‹œ๊ธ€ 3๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. → ์ฟผ๋ฆฌ 1๋ฒˆ ๋ฐœ์ƒ

3) Post๊ฐ€ EAGER์ธ ๊ฑธ ์•Œ๊ฒŒ ๋๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋น„์–ด์ ธ ์žˆ๋Š” ๊ฑธ ์•Œ๊ณ  ์ž‘์„ฑ์ž๋ฅผ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜ํ•˜๋‚˜ DB์— ๋ฌผ์–ด๋ณธ๋‹ค. Post1์„ ๋ณด๊ณ  SELECT * FROM member WHERE id = ?;๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋ชจ๋“  ๊ฒŒ์‹œ๊ธ€์„ ๋Œ๋ฉด์„œ ์ž‘์„ฑ์ž์˜ ์ •๋ณด๋ฅผ ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒŒ์‹œ๊ธ€์ด 3๊ฐœ๋ผ๋ฉด 3๋ฒˆ ๋ฌผ์–ด๋ณธ๋‹ค. → 3๊ฐœ์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒ, ์ด๊ฑธ N+1 ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

์š”์•ฝํ•ด๋ณด์ž๋ฉด, ๋จผ์ € SQL์„ ๋‚ ๋ฆฌ๊ณ  ๋ณด๋‹ˆ EAGER์ธ ๊ฑธ ๋‚˜์ค‘์— ์•Œ๊ฒŒ๋˜์–ด์„œ ๋ถ€๋žด๋ถ€๋žด ๋ถ€์กฑํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ„์šฐ๋ ค๊ณ  ์ถ”๊ฐ€ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๋งŒ์•ฝ ์กฐํšŒํ•  ๊ฒŒ์‹œ๊ธ€์ด ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ๋‹ค๋ฉด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

 

 

 

  • LAZY
// ์—”ํ‹ฐํ‹ฐ ์„ค์ •
@Entity
public class Post {

    // ์ง€์—ฐ๋กœ๋”ฉ
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "member_id")
    private Member member;
}
๊ฒŒ์‹œ๊ธ€์„ ๊ฐ€์ ธ์˜ค๋ผ๊ณ  ํ–ˆ์„ ๋•, ์ž‘์„ฑ์ž ์ด๋ฆ„์ด ํ”„๋ก์‹œ๋กœ ์˜จ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž‘์„ฑ์ž ์ด๋ฆ„์„ ์š”์ฒญํ•˜๊ฒŒ ๋˜๋ฉด ๊ทธ๋•Œ N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

1) SELECT * FROM post;๋กœ ๊ฒŒ์‹œ๊ธ€ 3๊ฐœ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž‘์„ฑ์ž ์ž๋ฆฌ๋Š” ํ”„๋ก์‹œ ์ƒํƒœ์ด๋‹ค. → ์ฟผ๋ฆฌ 1๋ฒˆ ๋ฐœ์ƒ

2) ์ด๋ฆ„์„ ๋ฌผ์–ด๋ดค๋‹ค. 1๋ฒˆ ๊ฒŒ์‹œ๊ธ€์˜ ์ž‘์„ฑ์ž ์ด๋ฆ„ ์ถœ๋ ฅ์„ ์‹œ๋„ํ•˜๋‹ˆ, ๋น„์–ด์žˆ๊ณ  ๊ทธ๊ฑธ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด SELECT * FROM member WHERE id = 1;์„ ๋ณด๋‚ธ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๊ฒŒ์‹œ๊ธ€์˜ ์ˆ˜๋งŒํผ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋œ๋‹ค. → 3๊ฐœ์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒ, ์ด๊ฑธ N+1 ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

LAZY๋ฅผ ์ผ์–ด๋„ ์ด๋Ÿฐ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด EAGER์ฒ˜๋Ÿผ ์„ฑ๋Šฅ์„ ๋–จ์–ด๋œจ๋ฆฐ๋‹ค. ๊ทธ๋ž˜์„œ ์ฟผ๋ฆฌ๊ฐ€ ๋งŽ์ด ๋ฐœ์ƒํ•  ๊ฒƒ ๊ฐ™์€ ์ƒํ™ฉ์—” @EntityGraph๋ฅผ ๋ถ™์—ฌ ํ•œ ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋“ค๊ณ ์˜ค๋„๋ก ํ•œ๋‹ค.

 

 

 

 


 

 

 

 

@EntityGraph์˜ ์‚ฌ์šฉ ์ด์œ 

  • ๊ทธ๋‹ˆ๊นŒ ๊ฒฐ๋ก ์ ์œผ๋กœ LAZY๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ง€์ •ํ–ˆ๋”๋ผ๋„ ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ์ง„์งœ ๊ฐ์ฒด๋กœ ๋ฐ๋ฆฌ๊ณ  ์˜ฌ ๋•Œ N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋‹ˆ ๊ทธ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ณ ์ž @EntityGraph๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • @EntityGraph๋ฅผ ์ ์šฉํ•œ ๋ฉ”์„œ๋“œ๋Š”, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ LAZY ์„ค์ •์„ ๋ฌด์‹œํ•˜๊ณ  SQL JOIN์„ ํ†ตํ•ด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜จ๋‹ค. ์ •์ ์ธ ์„ค์ •์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•œ ๊ฒƒ์ด๋‹ค.
@Entity
public class Post {

    // ์ง€์—ฐ๋กœ๋”ฉ ์„ค์ •
    @ManyToOne(fetch = FetchType.LAZY)
    private Member member;
}
public interface PostRepository extends JpaRepository<Post, Long> {

    // member๋„ ๊ฐ™์ด ๋ฐ๋ ค์™€.
    @EntityGraph(attributePaths = {"member"})
    List<Post> findAll();
}
findAll( )์ธ ํŠน์ • ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, @EntityGraph๋ฅผ ํ†ตํ•ด member๋„ ๊ฐ™์ด ๋ฐ๋ ค์˜ค๋ผ๊ณ  ์ž‘์„ฑํ–ˆ๋‹ค. Post์˜ ์ „์ฒด๋ฅผ ์กฐํšŒํ•  ๋•Œ ์ž‘์„ฑ์ž ์ด๋ฆ„๋„ ํ•œ ๋ฒˆ์— ์˜ค๋„๋ก ํ•œ๊ฑฐ๋‹ˆ, left outer join member m on p.member_id = m.id; ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์ด ํ•œ ๋ฒˆ์˜ ์ฟผ๋ฆฌ๋กœ ๋๋‚œ๋‹ค.

attributePaths๋Š” ์†์„ฑ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•œ ๊ฒƒ์ด๋‹ค. ์กฐํšŒํ•˜๊ณ  ์‹ถ์€ ์—ฐ๊ด€ ๊ด€๊ณ„์˜ ํ•„๋“œ ์ด๋ฆ„์„ attributePaths์— ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ์ง€๊ธˆ ์ด ์ฝ”๋“œ์—์„œ๋Š” ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•œ ์ž‘์„ฑ์ž๋ฅผ ์•Œ๊ณ  ์‹ถ์€๊ฑฐ๋‹ˆ, ๊ทธ ์ •๋ณด๊ฐ€ ๋“ค์–ด์žˆ์„ Member๋ฅผ ์ง€์ •ํ–ˆ๋‹ค.

์œ„์ชฝ ์„ค๋ช…์— left outer join member m on p.member_id = m.id; ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, Left Outer Join ์‚ฌ์šฉ์ด @EntityGraph์˜ ์ฃผ์š” ํŠน์ง•์ด๋‹ค. ์ด ๋ง์„ ์‰ฝ๊ฒŒ ํ’€์–ด์„œ ์„ค๋ช…ํ•˜๋ฉด ์™ผ์ชฝ ํ…Œ์ด๋ธ”์€ ๋ชจ๋‘ ๋ณด์—ฌ์ฃผ๊ณ  ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”(์—ฐ๊ด€๋ฐ์ดํ„ฐ)์€ ์žˆ์œผ๋ฉด ๊ฐ€์ ธ์˜ค๊ณ  ์—†์œผ๋ฉด ๋น„์›Œ๋‘๋ผ๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค. ๊ทธ๋Ÿผ ์™œ Left Outer Join์„ ์‚ฌ์šฉํ•˜๋Š”๊ฑธ๊นŒ?

์˜ˆ๋ฅผ ๋“ค์–ด์„œ 3๋ช…์˜ ํ•™์ƒ์ด ๊ฐ„์‹์„ ์‹ ์ฒญํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. A ํ•™์ƒ์€ ์ดˆ์ฝ”๋ฐ”, B ํ•™์ƒ์€ ์‚ฌํƒ•, C ํ•™์ƒ์€ ์‹ ์ฒญํ•˜์ง€ ์•Š์•˜๋‹ค. ์™ผ์ชฝ ํ…Œ์ด๋ธ”์—” ํ•™์ƒ A, B, C๊ฐ€ ์žˆ๊ณ  ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”์—” A(์ดˆ์ฝ”๋ฐ”), B(์‚ฌํƒ•)์ด ์žˆ๋‹ค. (C๋Š” ๊ฐ„์‹์„ ์‹ ์ฒญํ•˜์ง€ ์•Š์•˜์œผ๋‹ˆ ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”์—” ์—†๋‹ค)

ineer join(๋‚ด๋ถ€ ์กฐ์ธ)์€ [ ํ•™์ƒ๊ณผ ๊ฐ„์‹์ด ๋‘˜ ๋‹ค ์žˆ๋Š” ๊ฒฝ์šฐ๋งŒ ๊ฐ€์ ธ์™€ ]๋ผ์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ A(์ดˆ์ฝ”๋ฐ”)์™€ B(์‚ฌํƒ•)๋งŒ ๋‚˜์˜ค๊ณ  C๋Š” ์‚ฌ๋ผ์ง„๋‹ค.
left outer join(์™ผ์ชฝ ์™ธ๋ถ€ ์กฐ์ธ)์€ [ ํ•™์ƒ์€ ๋ชจ๋‘ ๋ณด์—ฌ์ค˜. ๋Œ€์‹  ๊ฐ„์‹์ด ์žˆ์œผ๋ฉด ์˜†์— ๋ถ™์ด๊ณ  ์—†์œผ๋ฉด null๋กœ ๋ณด์—ฌ์ค˜ ]๋ผ์„œ  A(์ดˆ์ฝ”๋ฐ”), B(์‚ฌํƒ•), C(NULL)๋กœ ํ•™์ƒ 3๋ช… ๋ชจ๋‘ ์œ ์ง€๋œ๋‹ค. right outer join์€ ๊ฐ„์‹์„ ๋ชจ๋‘ ๋ณด์—ฌ์ฃผ๋Š”๊ฑฐ๋‹ˆ๊นŒ C๋Š” ๋ˆ„๋ฝ๋˜๊ฒŒ ๋œ๋‹ค.

์ด๋ ‡๊ฒŒ @EntityGraph๊ฐ€ ์™œ left outer join์„ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์™ผ์ชฝ ํ…Œ์ด๋ธ”์€ ์ฃผ์ธ๊ณต์„ ๋ฐฐ์น˜ํ•ด์•ผํ•œ๋‹ค. ํ•ด๋‹น ์ฝ”๋“œ์—์„  ๊ฒŒ์‹œ๊ธ€์ด ์ฃผ์ธ๊ณต์ด๋‹ค. ๊ฒŒ์‹œ๊ธ€์„ ์กฐํšŒํ• ๊ฑด๋ฐ, ์ž‘์„ฑ์ž๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ์œผ๋ฉด ํ•จ๊ป˜ ๋ณด์—ฌ์ค˜๋ผ๊ณ  ํ•ด์•ผํ•œ๋‹ค. ๋งŒ์•ฝ @EntityGraph๊ฐ€ right outer join์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒŒ์‹œ๊ธ€์„ ์กฐํšŒํ•˜๋ ค๊ณ  ํ•œ๊ฑด๋ฐ, ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์€ ๋ฉค๋ฒ„๊นŒ์ง€ ๋ชจ๋‘ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. 

 

 

Q. @EntityGraph๋Š” ์–ธ์ œ ์จ์•ผํ• ๊นŒ?

A. LAZY๋ฅผ ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ๊ณณ์—์„œ ์—ฐ๊ด€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ๊บผ๋ฒˆ์— ํ•„์š”ํ•  ๋•Œ ํ•ด๋‹น ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์—๋งŒ @EntityGraph๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์˜ ํ•„๋“œ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์ฃผ๋ฌธ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•  ๋•Œ ์–ด๋–ค ์ƒํ’ˆ์ธ์ง€ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฌด์กฐ๊ฑด ์—ฎ์—ฌ ์žˆ์„ ๋•Œ ๋„ฃ๋Š”๊ฒŒ ์ข‹๋‹ค. ๋‚˜์ค‘์— ๋ชจ๋‹ˆํ„ฐ๋ง์„ ํ•ด๋ณด๊ณ  ์ฟผ๋ฆฌ๊ฐ€ ๋งŽ์ด ๋‚˜๊ฐ€๋Š” ๊ฑธ ํ™•์ธํ•˜๋ฉด ๊ทธ๋•Œ ์„ ํƒ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด๋„ ์ข‹๋‹ค. 

 

 

Q. ์ฃผ์˜ํ•ด์•ผํ•  ์ ?

A. ์ค‘๋ณต ๋ฐ์ดํ„ฐ์ด๋‹ค. ๋งŒ์•ฝ ๊ฒŒ์‹œ๊ธ€ 1๊ฐœ์— ๋Œ“๊ธ€์ด 3๊ฐœ๊ฐ€ ๋‹ฌ๋ ธ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. left join์„ ํ•˜๋ฉด ๊ฒฐ๊ณผ ํ‘œ์— ๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ์ด 3๋ฒˆ ์ค‘๋ณตํ•ด์„œ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค. ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ›์œผ๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์–ด์„œ, ์ด๋Ÿฐ ๊ฒฝ์šฐ distinct ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ Set ์ž๋ฃŒํ˜•์„ ์จ์„œ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•ด์•ผํ•œ๋‹ค.