π[Spring] μ°κ΄κ΄κ³ μ¬μ©μ κ³ λ €ν΄μΌ ν μ¬νλ€μ 무μμ΄ μμκΉμ?
- JPAμμ μ°κ΄κ΄κ³λ₯Ό μ¬μ©ν λλ μ¬λ¬ κ°μ§ μΈ‘λ©΄μ κ³ λ €ν΄μΌ ν©λλ€.
- μ°κ΄κ΄κ³λ₯Ό μ μ ν μ€μ νμ§ μμΌλ©΄ μ±λ₯ μ ν, 볡μ‘ν νΈλμμ κ΄λ¦¬, μ μ§λ³΄μμ± μ ν λ±μ λ¬Έμ λ₯Ό μ΄λν μ μκΈ° λλ¬Έμ λλ€.
1οΈβ£ μ°κ΄κ΄κ³ μ¬μ©μ κ³ λ €ν΄μΌ ν νλͺ©λ€.
1οΈβ£ μ°κ΄κ΄κ³μ λ°©ν₯(λ¨λ°©ν₯ vs μλ°©ν₯)
1οΈβ£ λ¨λ°©ν₯ μ°κ΄κ΄κ³.
- νμͺ½ μν°ν°λ§ λ€λ₯Έ μν°ν°λ₯Ό μ°Έμ‘°νλ κ΄κ³μ λλ€.
- λ¨λ°©ν₯ μ°κ΄κ΄κ³λ μ€κ³μ κ΄λ¦¬κ° κ°λ¨νκ³ μ±λ₯ μ΅μ νμλ μ 리ν©λλ€.
2οΈβ£ μλ°©ν₯ μ°κ΄κ΄κ³.
- μλ‘ μ°Έμ‘°νλ κ΄κ³λ‘, λ μν°ν° κ°μ κ΄κ³λ₯Ό λͺ
νν νκ³ κ°μ²΄ κ·Έλν νμμ΄ λ μ¬μμ§λλ€.
- νμ§λ§ μλ°©ν₯ μ°κ΄κ΄κ³λ μλ‘ μ°Έμ‘°νλ©΄μ 볡μ‘μ±μ΄ μ¦κ°νκ³ , λ°μ΄ν° μ§λ ¬ν κ³Όμ μμ 무ν 루νκ° λ°μν μ μμΌλ―λ‘ μ μ€νκ² μ¬μ©ν΄μΌ ν©λλ€.
πββοΈ λ°μ΄ν° μ§λ ¬ν(Serialization)
λ°μ΄ν° μ§λ ¬ν(Serialization)λ κ°μ²΄ λλ λ°μ΄ν° ꡬ쑰λ₯Ό μ μ₯νκ±°λ μ μ‘ν μ μλ νμμΌλ‘ λ³ννλ κ³Όμ μ μλ―Έν©λλ€.
μ΄λ₯Ό ν΅ν΄ λ©λͺ¨λ¦¬μμ κ°μ²΄λ‘ μ‘΄μ¬νλ λ°μ΄ν°λ₯Ό νμΌλ‘ μ μ₯νκ±°λ λ€νΈμν¬λ₯Ό ν΅ν΄ λ€λ₯Έ μμ€ν μΌλ‘ μ μ‘ν μ μμ΅λλ€.
λ°λλ‘, μμ§λ ¬ν(Deserialization)λ μ§λ ¬νλ λ°μ΄ν°λ₯Ό λ€μ μλμ κ°μ²΄λ λ°μ΄ν° κ΅¬μ‘°λ‘ λ³΅μνλ κ³Όμ μ λλ€.
3οΈβ£ μ ν κΈ°μ€.
- κ°λ₯νλ©΄ λ¨λ°©ν₯ μ°κ΄κ΄κ³λ₯Ό μ°μ μΌλ‘ μ€κ³νκ³ , μλ°©ν₯ μ°κ΄κ΄κ³κ° λ°λμ νμν κ²½μ°μλ§ μ€μ νλ κ²μ΄ μ’μ΅λλ€.
2οΈβ£ μ°κ΄κ΄κ³μ μ£ΌμΈ(Owning Side)
- μλ°©ν₯ μ°κ΄κ΄κ³μμλ μΈλ ν€(Foreign Key)λ₯Ό κ΄λ¦¬ν μ°κ΄κ΄κ³μ μ£ΌμΈμ λͺ νν μ§μ ν΄μΌ ν©λλ€.
- μ°κ΄κ΄κ³μ μ£ΌμΈμ λ°μ΄ν°λ² μ΄μ€μ μ€μ μΈλ ν€(Foreign Key)λ₯Ό μ μ₯νλ μν°ν°λ‘, μ£ΌμΈμ΄ μλ μν°ν°μμ μ°κ΄κ΄κ³λ₯Ό μ€μ ν΄λ λ°μ΄ν°λ² μ΄μ€μλ λ°μνμ§ μμ΅λλ€.
- μ£ΌμΈμ μ ννκ² μ€μ νμ§ μμΌλ©΄ λ°μ΄ν° λΆμΌμΉκ° λ°μν μ μμΌλ©°, λ°μ΄ν°λ² μ΄μ€μ λΆνμν μΏΌλ¦¬κ° λ°μν μ μμ΅λλ€.
3οΈβ£ μ§μ° λ‘λ©(Lazy Loading)κ³Ό μ¦μ λ‘λ©(Eager Loading)
1οΈβ£ μ§μ° λ‘λ©(Lazy Loading).
- μ°κ΄λ μν°ν°λ₯Ό μ€μ λ‘ μ¬μ©ν λ λ°μ΄ν°λ₯Ό λ‘λνλ λ°©μμ λλ€.
- κΈ°λ³Έμ μΌλ‘ μ°κ΄ κ΄κ³λ μ§μ° λ‘λ©μ μ¬μ©νλ κ²μ΄ μ±λ₯μ μ 리νλ©°, νμν μκ°μλ§ λ°μ΄ν°λ₯Ό κ°μ Έμ μ±λ₯μ μ΅μ νν μ μμ΅λλ€.
2οΈβ£ μ¦μ λ‘λ©(Eager Loading).
- μν°ν°λ₯Ό μ‘°νν λ μ°κ΄λ λͺ¨λ λ°μ΄ν°λ₯Ό μ¦μ λ‘λνλ λ°©μμΌλ‘, νμ μ΄μμΌλ‘ λ§μ λ°μ΄ν°λ₯Ό κ°μ Έμ N+1 λ¬Έμ λ₯Ό μ λ°ν μ μμ΅λλ€.
3οΈβ£ μ ν κΈ°μ€.
- μΌλ°μ μΌλ‘ μ§μ° λ‘λ©(Lazy Loading)μ κΈ°λ³ΈμΌλ‘ νκ³ , μ±λ₯μ ν° μν₯μ΄ μλ κ²½μ°μλ§ μ¦μ λ‘λ©(Eager Loading)μ μ¬μ©ν©λλ€.
- μ¦μ λ‘λ©(Eager Loading)μ μ¬μ©νλ©΄ μ°κ΄λ λͺ¨λ λ°μ΄ν°λ₯Ό ν λ²μ κ°μ Έμ€λ―λ‘, νΉμ μ‘°ν μ ν λ²μ μΏΌλ¦¬λ‘ μ¬λ¬ λ°μ΄ν°λ₯Ό κ°μ ΈμμΌ ν λ μ μ©ν©λλ€.
4οΈβ£ νμΉ μ‘°μΈ(Fetch Join)
1οΈβ£ μ§μ° λ‘λ©(Lazy Loading)μμμ νμΉ μ‘°μΈ(Fetch Join)
- μ§μ° λ‘λ©(Lazy Loading)μμ N+1 λ¬Έμ λ₯Ό λ°©μ§νκ³ νμν λ°μ΄ν°λ₯Ό ν λ²μ κ°μ Έμ€κΈ° μν΄ νμΉ μ‘°μΈ(Fetch Join)μ μ¬μ©ν©λλ€.
2οΈβ£ JPQL 쿼리μμ νμΉ μ‘°μΈ(Fetch Join)
- νμΉ μ‘°μΈ(Fetch Join)μ JPQL 쿼리μμ μ°κ΄λ λ°μ΄ν°λ₯Ό μ‘°μΈνμ¬ ν¨κ» λ‘λνλ λ°©μμΌλ‘, μ±λ₯ μ΅μ νμ μ μ©ν©λλ€.
-
3οΈβ£ μ ν κΈ°μ€.
- νμΉ μ‘°μΈ(Fetch Join)μ νμν κ²½μ°μλ§ μ¬μ©νλ©°, 쿼리 볡μ‘μ±μ μ¦κ°μν€λ―λ‘ λ¬΄λΆλ³νκ² μ¬μ©νμ§ μλλ‘ μ£Όμν΄μΌ ν©λλ€.
5οΈβ£ Cascade μ΅μ κ³Ό orphanRemoval
1οΈβ£ Cascade μ΅μ .
- λΆλͺ¨ μν°ν°μμ μμ μν°ν°λ₯Ό ν¨κ» κ΄λ¦¬ν μ μλλ‘ CascadeType.PERSIST, CascadeType.REMOVE λ±μ μ΅μ
μ μ€μ ν μ μμ΅λλ€.
- μλ₯Ό λ€μ΄, λΆλͺ¨ μν°ν°λ₯Ό μ μ₯ν λ μμ μν°ν°λ μλμΌλ‘ μ μ₯λκ±°λ μμ ν λ μμ μν°ν°λ ν¨κ» μμ λ μ μμ΅λλ€.
2οΈβ£ orphanRemoval μ΅μ .
- λΆλͺ¨μμ κ΄κ³κ° λκΈ΄ μμ μν°ν°λ₯Ό μλμΌλ‘ μμ νλλ‘ μ€μ ν μ μμ΅λλ€.
- μλ₯Ό λ€μ΄, λΆλͺ¨ μν°ν°μμ μμ μν°ν° 리μ€νΈμμ μ κ±°λλ©΄ λ°μ΄ν°λ² μ΄μ€μμλ μλμΌλ‘ μμ λ©λλ€.
3οΈβ£ μ ν κΈ°μ€.
- Cascadeμ orphanRemovalμ λΆλͺ¨μ μμ κ° μλͺ
μ£ΌκΈ°κ° μμ ν μΌμΉν λλ§ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
- κ·Έλ μ§ μμΌλ©΄ μλμΉ μμ λ°μ΄ν° μμ λ μμμ± μ ν λ¬Έμ κ° λ°μν μ μμ΅λλ€.
πββοΈ μμμ± μ ν(Persistence Propagation)
JPAμμ νλμ μν°ν°μ μνν μμμ± μμ μ΄ μ°κ΄λ λ€λ₯Έ μν°ν°μ μλμΌλ‘ μ νλλ κΈ°λ₯μ μλ―Έν©λλ€.
μ΄λ₯Ό ν΅ν΄ λΆλͺ¨ μν°ν°κ° νΉμ μμμ± μν(μ: μ μ₯, μμ , λ³ν© λ±)λ‘ λ³κ²½λ λ, μμ μν°ν°λ λμΌν μνλ‘ μ μ΄λ μ μλλ‘ κ΄λ¦¬ν μ μμ΅λλ€.JPAμμλ μ΄λ₯Ό μν€ Cascade μ΅μ μ μ 곡νλ©°, μ£Όλ‘ μ°κ΄λ μ¬λ¬ μν°ν°κ° νλμ μλͺ μ£ΌκΈ°λ₯Ό κ°μ§ λ μ¬μ©λ©λλ€.
μ¦, λΆλͺ¨μ μμ κ΄κ³λ₯Ό κ°μ§ μν°ν°κ° μμ λ, λΆλͺ¨ μν°ν°λ₯Ό μμ μνλ‘ λ§λ€κ±°λ μμ νλ©΄, μμ μν°ν°λ κ°μ μμ μ΄ μλμΌλ‘ μ΄λ£¨μ΄μ§λλ€.
6οΈβ£ λ°μ΄ν° μ‘°ν μ μ΅μ ν.
- μ°κ΄κ΄κ³λ₯Ό ν΅ν΄ κ°μ²΄ κ·Έλνλ₯Ό νμν λ λΆνμν λ°μ΄ν°κ° κ³Όλνκ² μ‘°νλμ§ μλλ‘ JPQL, λ€μ΄ν°λΈ SQL, DTO λ±μ νμ©ν΄ νμν λ°μ΄ν°λ§ κ°μ Έμ€λ λ°©λ²μ κ³ λ €ν΄μΌ ν©λλ€.
1οΈβ£ DTOλ₯Ό μ¬μ©ν λ°μ΄ν° μ μ‘.
- μν°ν°μ λͺ¨λ λ°μ΄ν°λ₯Ό ν΄λΌμ΄μΈνΈλ‘ 보λ΄λ λμ , νμν μ λ³΄λ§ λ΄μ DTO(Data Transfer Object)λ₯Ό ν΅ν΄ μ±λ₯μ μ΅μ νν μ μμ΅λλ€.
7οΈβ£ μ°κ΄κ΄κ³ μ€μ μ΄ λ°λμ νμνμ§ κ²ν .
- λͺ¨λ κ΄κ³λ₯Ό μ°κ΄κ΄κ³λ‘ μ€μ ν νμλ μμ΅λλ€.
- λ¨μν IDλ§ νμνκ±°λ λ€λ₯Έ ν μ΄λΈμμ νΉμ λ°μ΄ν°λ₯Ό μ‘°νν λλ§λ€ μ¬μ©λλ κ΄κ³λΌλ©΄, κ΅³μ΄ μ°κ΄κ΄κ³λ₯Ό μ€μ νμ§ μκ³ IDλ₯Ό μ¬μ©νμ¬ μ‘°ννλ κ²μ΄ μ±λ₯μ μ 리ν μ μμ΅λλ€.
- λ°μ΄ν°λ² μ΄μ€μ κ΄κ³λ₯Ό λͺ¨λ μν°ν° κ° μ°κ΄κ΄κ³λ‘ μ€μ νλ©΄ μ€νλ € μ€κ³κ° 볡μ‘ν΄μ§κ³ μ±λ₯μ ν΄μΉ μ μμ΅λλ€.
8οΈβ£ λ°μ΄ν° μΌκ΄μ± λ° λ¬΄κ²°μ± κ΄λ¦¬.
- μ°κ΄κ΄κ³λ₯Ό ν΅ν΄ λ°μ΄ν° μΌκ΄μ±μ μ μ§ν μ μλλ‘, νΈλμμ κ΄λ¦¬μ μ°κ΄ κ΄κ³ μ€μ μ μ μ€νκ² ν΄μΌ ν©λλ€.
- μμ μν°ν°κ° λΆλͺ¨ μν°ν°μ κ°νκ² μ’ μλ κ²½μ°(μ: μ£Όλ¬Έκ³Ό μ£Όλ¬Έ νλͺ©)μλ μΌκ΄μ±μ μ μ§ν μ μλλ‘ μ°κ΄κ΄κ³λ₯Ό μ μ νκ² μ€μ νκ³ , Cascade μ΅μ μ ν΅ν΄ μλͺ μ£ΌκΈ°λ₯Ό ν¨κ» κ΄λ¦¬νλ κ²μ΄ μ’μ΅λλ€.
9οΈβ£ μμ½.
- μ°κ΄κ΄κ³λ₯Ό μ¬μ©ν λ κ³ λ €ν΄μΌ ν μ¬νμ λ€μκ³Ό κ°μ΅λλ€.
- λ¨λ°©ν₯κ³Ό μλ°©ν₯ μ€ νμν λ°©μμ μ ννκ³ , μλ°©ν₯ κ΄κ³μ κ²½μ° λ°λμ μ£ΌμΈμ λͺ νν μ€μ ν©λλ€.
- μ§μ° λ‘λ©(Lazy Loading)μ κΈ°λ³ΈμΌλ‘ μ¬μ©νλ©° νμν λλ§ μ¦μ λ‘λ©(Eager Loding)μ΄λ νμΉ μ‘°μΈ(Fetch Join)μ μ¬μ©ν©λλ€.
- Cascade μ΅μ κ³Ό orphanRemovalμ μ μ€νκ² μ€μ νμ¬ λΆλͺ¨-μμ κ΄κ³λ₯Ό κ΄λ¦¬νκ³ , μλνμ§ μμ λ°μ΄ν° μμ λ₯Ό λ°©μ§ν©λλ€.
- μ±λ₯μ κ³ λ €νμ¬ λ°μ΄ν° μ‘°ν μ μ΅μ ννκ³ , νμνμ§ μμ κ΄κ³λ μ°κ΄κ΄κ³λ μ€μ νμ§ μλ κ²μ΄ μ’μ΅λλ€.