-
Notifications
You must be signed in to change notification settings - Fork 0
๐ ๏ธ ๋ถ๋ก : ์ฌ์ฐจ์ ์ฐจ JPA ์ ์๊ธฐ
JPA๋ฅผ ์ ๋ชจ๋ฅด๊ณ ์ฐ๋ค๋ณด๋ ์ด๋ฒ ์ฌ์ด๋์์ ๊ฝค๋ ๋ง์ ๊ณค์์ ์น๋ ๋ค. ๋ฌผ๋ก ์ ์๋๋ค ์ถ์ ๋ ๊ฒ์ํ๋ฉด ํด๊ฒฐ์ฑ ์ด ๋ค ๋์์ง๋ง, ์ด๋ ค์ด ์ผ์ด์ค๋ ๊ณ ๋ฏผ์ ๋ง์ด ํ๋ค. ์ด๋ฒ ๊ธฐํ์ ์ฌ์ํ ๋ฌธ์ ๋ถํฐ ์ ๋ฆฌํด์ ํํ์ด ํ์ธํด๋ณด๋ ค ํ๋ค.
ํ์์ด ๊ฐ์ง ์ฟ ํฐ ์ด๋ ฅ(unused_coupon_book
)์ ํ์์ด ์ง์ ๊ด๋ฆฌํด์ผ ํ๋ค๊ณ ์๊ฐํด Cascade ALL
๋ก ์ค์ ํ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
@Entity
@Table(name = "member")
class MemberEntity(
@ManyToMany(
targetEntity = CouponEntity::class,
cascade = [CascadeType.ALL],
)
@JoinTable(
name = "unused_coupon_book",
joinColumns = [JoinColumn(name = "member_id")],
inverseJoinColumns = [JoinColumn(name = "coupon_id")],
)
var unusedCoupons: List<CouponEntity>,
}
์ง๋๊ฐ๊ธฐ ์ ์ Cascade๋ฅผ ์ ๋ฆฌํด๋ดค๋ค. Cascade ๋ ์ํฐํฐ ์ํ์ ๋ฐ๋ผ ์ด๋ป๊ฒ ๋์ํ ์ง ๊ฒฐ์ ํ๋ ์ค์ ๊ฐ์ด๋ค.
- PERSIST : ์ํฐํฐ๋ฅผ ์์ํ ํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ์์ํํ๋ค.
- MERGE : ์ํฐํฐ๋ฅผ ๋ณํฉํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ๋ณํฉํ๋ค.
- REMOVE : ์ํฐํฐ ์ญ์ ํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์ญ์ ํ๋ค.
- REFRESH : ์ํฐํฐ ๊ฐฑ์ ํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ๊ฐฑ์ ํ๋ค.
Cascade๋ unused_coupon_book
์ ํ๊ฒ์ผ๋ก ํ์ง ์๊ณ coupon entity
์ ํ๊ฒ์ผ๋ก ํ๋ค.
์ฐธ๊ณ ์๋ฃ : JPA Hibernate many-to-many cascading
์ง์ ํ
์คํธํ์ ๋ CascadeType.Persist
์ค์ ๊ณผ ํจ๊ป member entity
+ coupon entity
๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ coupon entity
๊ฐ ์ ์ฅ๋๋ค.
CascadeType.Remove
์ค์ ์ member entity
๊ฐ ์ญ์ ๋๋ฉด coupon entity
๊ฐ ์ญ์ ๋์ด์ผ ํ๋๊ฒ ๊ทธ๋ ์ง ์์๋คโฆ? ํ
์คํธ ๋ฐฉ๋ฒ์ด ์๋ชป๋๋ ํด์ entity manager
๋ก remove
๋ฉ์๋๋ฅผ ์คํํด๋ ๋์ํ์ง ์์๋ค.
3.X ๋ฒ์ ์ผ๋ก ๋์ด์ค๋ฉด์ ๋์์ด ๋ณ๊ฒฝ๋๋ ์๊ฐ์ด ๋ ๋คโฆ ๊ด๋ จ ๋ฌธ์๋ ํ์ธํ๊ธฐ ์ด๋ ต๋ค.
์์ ์ํ์์ ๋ถ๋ฆฌ๋(deteched
) ์ํฐํฐ๋ฅผ persist()
๋ฉ์๋๋ก ์์ํํ ๋ ๋ฐ์ํ๋ฉฐ ๋ค์ ์ค ํ๋๋ฅผ ์ ํํ๋ฉด ๋๋ค.
- ์ฐ๊ด ๊ด๊ณ ๋งคํ์ ํตํด
CouponEntity
๊ฐ ์กฐํ๋จ. - ์กฐํ๋
CouponEntity
๊ฐ ์ค์์ ์ํ๊ฐ ๋จ.
ํ์์ ์กด์ฌํ๋ ์ฟ ํฐ์ ์ฐพ์ ์ฐ๊ด ๊ด๊ณ๋ฅผ ๋งบ๋๋ค. ํ์์ด ์์ด์ง๋ฉด ์ฐ๊ด๋ ์ฟ ํฐ์ ์์ด์ง๋ฉด ์๋๋ค. ๊ทธ๋์ coupon entity
์ ์์ ์ํ๋ฅผ ์ ์ง ํ๋ฉฐ ์์ ๋ ์ด์ ๋ ์๋ค.
๐ ๏ธ ์ ๋ฆฌ์ค
์ธ์
์ด ์๋ ์ํ๋ก lazy ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ฒ ๋๋ฉด ํ
๋น์ด ์์ด์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค. JPA์์ ์ธ์
์ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์ด๋ฉฐ EntityManger
๊ฐ ์ธ์
์ญํ ์ ์ํํ๋ค. EntityManger
๋ฅผ ํตํด ํธ๋์ญ์
์ ์คํํ๊ณ ์ปค๋ฐํ๋ฉฐ ํ์ ์ ์ธ ์ธ์
์ ์ด์ด ์ง์ฐ ๋ก๋ฉ์ด ๊ฐ๋ฅํ๊ฒ ํ๋ค. ์ฆ, ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์์ฒ๋ผ ํธ๋์ญ์
๋ด๋ถ์์ ์ ๊ทผํด์ผ ํ๋ค.
fun find() {
em.transaction.begin()
val member = repoository.find() // ๋ฐ์ดํฐ ์กฐํ ์์ญ
println(member.unusedCoupons.size) // ๋ฐ์ดํฐ ์ ๊ทผ ์์ญ
em.transaction.commit()
}
๋น์ฆ๋์ค ๋ก์ง์ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ค ๋ณด๋ ํ์ ๋ ์ด์ด์์ JPA ๊ด๋ จ ํ ์คํธ๋ฅผ ์ํ ํ ์ ์์๋ค. ํ ์คํธ๋ฅผ ์งํํ๋ ค๋ฉด ํ์ ๋ ์ด์ด๋ ํธ๋์ญ์ ์ผ๋ก ์๋กญ๊ฒ ๋ฌถ๊ฑฐ๋ ์ฆ์ ๋ก๋ฉ์ด ๋๊ฒ ์ค์ ํด์ผ ํ๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์กฐํํ๋ ์์ญ๊ณผ lazy ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์์ญ์ ๊ฐ์ ์ธ์ (ํธ๋์ญ์ )์ผ๋ก ํฌํจ์ํค๊ฑฐ๋ ์ฆ์ ๋ก๋ฉ์ด ๋๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ์ด๋ค.
- ํธ๋์ญ์ ๋จ์๋ก ๋ฌถ๋๋ค.
- ์ฆ์ ๋ก๋ฉ์ด ๋๊ฒ ํ๋ค.
์ฃผ์ํ ์ ์ ํ ์คํธ๋ฅผ ์ํ ์ฝ๋๊ฐ ์์ฑ๋ ์ ์ธ๋ฐ, ์ฆ์ ๋ก๋ฉ์ ํ๋ ๊ฒฝ์ฐ ํ ์คํธ๋ก ์ธํด ํ๋ก๋ํธ ์ฑ๋ฅ์ด ๋ณํํ๋ค๋ ๋ฌธ์ ์ ์ด ์์๊ณ , ํธ๋์ญ์ ์ ์ด๋ฏธ ํธ๋์ญ์ ์ด ์คํ๋๋ฉด ๊ธฐ์กด ํธ๋์ญ์ ์ ์ ์งํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ์ํฅ์ ์ฃผ์ง ์์๋ค. ๋ํ ์ฆ์ ๋ก๋ฉ ํ ๋งํผ ํด๋น ํ๋๊ฐ ํญ์ ํ์ํ์ง ์์์ ํธ๋์ญ์ ์์ญ์ ๋ฎ์ด์ฐ๋๋ก ์์ ํ๋ค.
ํ ์คํธ ํ ๋ JPA๋ฅผ ์คํํ๊ธฐ ์ํด ๋๋ถ๋ถ์ ๋ ์ด์ด์ ํธ๋์ญ์ ์ ๋ถ์ฌ์ผ ํ๋ ๋์ฐธ์ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์ฑ๋ฅ์๋ ์ฐจ์ด๊ฐ ์์ง๋ง ํ ์คํธ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง ์ ์๋ค. ์ ์ ํ๊ฒ ์ ๊ณ ๋ฏผํด์ ์ ํํ๋๋ก ํ์.