๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ๋ฐœ/JPA

[JPA] @OneToMany - ์ž์‹ ํ…Œ์ด๋ธ”(๊ด€๊ณ„ Entity)์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฐ€์ ธ์˜ค๊ธฐ

by ynzu๐Ÿค 2021. 11. 26.
๋ฐ˜์‘ํ˜•

JPA๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด LAZY ํŒจ์น˜ํƒ€์ž…์œผ๋กœ relation์ด ๋‹ฌ๋ ค ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ n+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

์ด๋Ÿด ๋•Œ๋Š” @EntityGrapth๋งŒ ๋‹ฌ์•„์ฃผ๋ฉด joinํ•˜์—ฌ ํ•œ๋ฒˆ์— selectํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์•„๋ž˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.

 

Product ํ…Œ์ด๋ธ”๊ณผ Sample ํ…Œ์ด๋ธ”์€ 1:N ๊ด€๊ณ„์ด๋‹ค.

๋”ฐ๋ผ์„œ sampleList์— @OneToMany ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค. 

(๋ฐ˜๋Œ€๋กœ Sample ์—”ํ‹ฐํ‹ฐ์— Product๋ฅผ @ManyToOne ์„ค์ •ํ•ด์ฃผ์–ด๋„ ๋œ๋‹ค)

@Entity
@ToString
@Table(name = "PRODUCT")
public class Product{
	
    @Id
    @Column(name = "PRODUCT_ID", columnDefinition ="VARCHAR(36)")
    private String productId;
    
    //์ƒ๋žต
    
    @OneToMany
    @JoinColumns({
    @JoinColumn(name = "SAMPLE_ID", referencedColumnName = "SAMPLE_ID", columnDefinition ="VARCHAR(36)", nullable = false, insertable = false, updatable = false),
    })
    @OnDelete(action= OnDeleteAction.CASCADE)
    private List<Sample> sampleList;
}

@OneToMany ์†์„ฑ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค.

  • targetEntity
  • cascade
  • fetch
  • mappedBy
  • orphanRemoval

์—ฌ๊ธฐ์„œ fetch๋Š” ๊ด€๊ณ„ Entity์˜ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ ์ „๋žต์„ ๊ฒฐ์ •ํ•˜๋ฉฐ EAGER, LAZY๊ฐ€ ์žˆ์œผ๋ฉฐ, ๋”ฐ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์€ LAZY์ด๋‹ค.

EAGER๋กœ ์„ค์ •ํ•  ๊ฒฝ์šฐ ๊ด€๊ณ„๋œ Entity์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ฝ์–ด์˜ค๊ณ , LAZY๋กœ ์„ค์ •ํ•  ๊ฒฝ์šฐ ์‹ค์ œ๋กœ ์š”์ฒญํ•˜๋Š” ์ˆœ๊ฐ„์— ๊ฐ€์ ธ์˜จ๋‹ค.

๋”ฐ๋ผ์„œ ์—”ํ‹ฐํ‹ฐ์— EAGER ํ˜น์€ LAZY ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ ์„ ํƒํ•˜์—ฌ ์„ธํŒ…ํ•ด์•ผ ํ•˜๋Š”๋ฐ ๋ณธ์ธ์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์กฐํšŒํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

(ํ•„์š”ํ•˜์ง€ ์•Š์€๋ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์€ ํšจ์œจ์ด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์—..)

 

 

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

๋จผ์ € @OneToMany(fetch = FetchType.LAZY) ๋กœ ์„ค์ • ํ•˜์—ฌ ์š”์ฒญํ•˜๋Š” ์ˆœ๊ฐ„์— ๊ฐ€์ ธ์˜ค๋„๋ก ํ•˜์˜€๋‹ค.

Product Repository์—์„œ findAllById ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด Sample์„ ์ œ์™ธํ•˜๊ณ  Product์—์„œ๋งŒ ์กฐํšŒํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ฉด ๋˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์กฐํšŒ๋œ Product ๋ฐ์ดํ„ฐ์—์„œ Sample์— ์ ‘๊ทผํ•˜๋ฉด ๋‹ฌ๋ ค์žˆ๋Š” Sample ๊ฐœ์ˆ˜ ๋งŒํผ select ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฐ๋‹ค. (n+1๋ฌธ์ œ ๋ฐœ์ƒ)

 

Repository๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด @EntityGraph ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ค์ •ํ•˜๋ฉด join ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

@EntityGraph(attributePaths = {"sampleList"})
List<Product> findAllById(String product_id);

FetchType.LAZY๋กœ ์„ค์ •ํ•˜๊ณ , repository์—์„œ ์ด๋ ‡๊ฒŒ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ @EntityGraph ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ค์ •ํ•˜์—ฌ join ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ์กฐํšŒํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€