Tistory λΈλ‘κ·Έ ν¬μ€ν λ°λ‘κ°κΈ°
JPAμ Persistence Context(μμμ± μ»¨ν μ€νΈ)λ μν°ν°λ₯Ό μꡬ μ μ₯νλ νκ²½μ λλ€.
JPAλ μν°ν° κ΄λ¦¬λ₯Ό μν΄ μ¬λ¬κ°μ§ κΈ°λ₯μ μ 곡νλλ° κ·Έ κΈ°λ°μ΄ λλ κ²μ΄ λ°λ‘ μμμ± μ»¨ν μ€νΈ μ λλ€. (κ°μ₯ μ€μ)
JPAλ μν°ν°λ₯Ό λ°μ΄ν°λ² μ΄μ€κ° μλ μν°ν° 맀λμ λ₯Ό ν΅ν΄ μ κ·Ό κ°λ₯ν νΉμ νκ²½μ μ μ₯ν λ€ μ¬μ©ν©λλ€.
μ΄λ₯Ό μ΄ν΄νκΈ° μν΄μλ μν°ν°μ μλͺ μ£ΌκΈ°μ λν΄ μμμΌ ν©λλ€.
μν°ν°μ μλͺ μ£ΌκΈ°μλ λΉμμ, μμ, μ€μμ, μμ μ΄λ κ² 4κ°μ§κ° μμ΅λλ€.
- λΉμμ (new/transient)
λΉμμ μνλ, μν°ν° κ°μ²΄λ₯Ό μμ±μ νμ§λ§ μμμ± μ»¨ν μ€νΈμλ κ΄κ³κ° μ ν μλ μμ ν μλ‘μ΄ μνλ₯Ό λ»ν©λλ€.
- μμ (managed)
μμ±ν μν°ν° κ°μ²΄λ₯Ό μμ±ν λ€ μν°ν° 맀λμ λ₯Ό ν΅ν΄ μμμ± μ»¨ν μ€νΈμ μ μ₯λ μνλ₯Ό λ»ν©λλ€.
μν°ν° 맀λμ μ persist
λ©μλλ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό μμμ± μ»¨ν
μ€νΈμ λ±λ‘ν μ μμ΅λλ€.
κ°μ²΄λ₯Ό μλ‘ μμ±ν λλ μμ μνλ₯Ό λ§λ€μ΄μ€ μ μμ§λ§, μ΄λ―Έ λ°μ΄ν°λ² μ΄μ€μ μ‘΄μ¬νλ λ°μ΄ν°μ κ²½μ°μλ μμ μνλ₯Ό λ§λ€μ΄μ€ μ μμ΅λλ€.
νΉμ κ°μ²΄ μ‘°ν μ μμ μνκ° μλλΌλ©΄ DB μ‘°νλ₯Ό ν΅ν΄ 1μ°¨ μΊμμ λ±λ‘ν΄μ μμ μνλ₯Ό λ§λ€μ΄μ€λλ€. (1μ°¨ μΊμμ λν λΆλΆμ μλμμ μ‘°κΈ λ μμΈν μμλ³΄κ² μ΅λλ€.)
μμ μνκ° λλ€κ³ ν΄μ DB μΏΌλ¦¬κ° λ°λ‘ λ λΌκ°λ κ²μ΄ μλκ³ νΈλμμ μ μ»€λ° μμ μ DB μΏΌλ¦¬κ° λ λΌκ°λλ€.
- μ€μμ (detached)
μμμ± μ»¨ν μ€νΈλ₯Ό ν΅ν΄ κ΄λ¦¬λκ³ μλ μν°ν° κ°μ²΄κ° λΆλ¦¬λ μνλ₯Ό λ»ν©λλ€.
μ€μμ μνκ° λλ©΄ μμμ± μ»¨ν μ€νΈκ° μ 곡νλ κΈ°λ₯λ€μ μ¬μ©ν μ μκΈ° λλ¬Έμ κ±°μ μ¬μ©ν μΌμ΄ μμ΅λλ€.
- μμ (removed)
μ΄λ¦ κ·Έλλ‘ μμ λ μνλ₯Ό λ»ν©λλ€.
μμμ± μ»¨ν μ€νΈλ μ΄λ€ μ΄μ λ€μ μ 곡νλμ§ μμλ³΄κ² μ΅λλ€.
μμμ± μ»¨ν μ€νΈ λ΄λΆμλ 1μ°¨ μΊμκ° μ‘΄μ¬ν©λλ€.
κ°μ²΄κ° μμμνκ° λλ©΄ 1μ°¨ μΊμμ key, value ννλ‘ λ±λ‘λ©λλ€.
μ¬κΈ°μ keyλ pkλ‘ λ§΅νν κ°μ΄κ³ , κ°μ μ μ₯ν μν°ν° κ°μ²΄ μμ²΄κ° λ©λλ€.
JPAλ μ‘°ν μ DB μ‘°νμ μμ 1μ°¨ μΊμλ₯Ό λ¨Όμ νμΈνκΈ° λλ¬Έμ, 1μ°¨ μΊμμ μ‘°ννκ³ μ νλ μν°ν° κ°μ²΄κ° μ‘΄μ¬νλ€λ©΄ DBκΉμ§ κ° νμμμ΄ 1μ°¨ μΊμμμ ν΄λΉ κ°μ²΄λ₯Ό κ°μ Έμ¬ μ μμ΅λλ€.
μ΄ κ³Όμ μμ λ§μ½ μ‘°ν μ 1μ°¨ μΊμμ μνλ μν°ν° κ°μ²΄κ° μλ€λ©΄, DBμμ κ°μ Έμ 1μ°¨ μΊμμ μ μ₯ ν λ°νν©λλ€.
μ΄νμ κ°μ κ°μ²΄ μ‘°ν μ 1μ°¨ μΊμμ μ μ₯ν κ°μ²΄λ₯Ό λ°ννκ² λλ κ²μ΄μ£ .
μΌλ°μ μΌλ‘ μ°λ¦¬κ° μκ³ μλ μΊμμ κ°λ κ³Ό κ°μ΅λλ€.
νμ§λ§ μ΄ 1μ°¨ μΊμλΌλ κ²μ νλμ DB νΈλμμ λ¨μ λμλ§ μ΄μ μμ΅λλ€. κ³ κ°μ μμ² λ€μ΄μμ λΉμ¦λμ€ λ‘μ§μ΄ μ λΆ μνλ ν λλλ²λ¦¬λ©΄ μ¬λΌμ§κ² λ©λλ€.
κ·Έλμ λμμμ²μ΄ λ§μ λμ ν° μ±λ₯ κ°μ ν¨κ³Όλ κΈ°λνκΈ°λ μ΄λ ΅μ΅λλ€.
JPAλ κ°μ νΈλμμ μμ μ‘°νν μν°ν°λ₯Ό λ€μ μ‘°νν κ²½μ°, μΊμ(1μ°¨ μΊμ)λ₯Ό ν΅ν΄ λΆλ¬μ€κΈ° λλ¬Έμ λͺ λ²μ νΈμΆνλ μΆκ° SQLλ¬Έ νΈμΆ μμ΄λ κ°μ μν°ν°μμ 보μ₯ν΄μ€λλ€.
1μ°¨ μΊμλ‘ REPEATABLE READ 격리 μμ€μ μ ν리μΌμ΄μ λ 벨μμ μ 곡ν΄μ£Όλ μ μ΄μ£ .
User user1 = em.find(User.class, 1L);
User user2 = em.find(User.class, 1L);
// λμΌμ± 보μ₯ (true)
System.out.println(user1 == user2);
μμμ± μ»¨ν μ€νΈμλ 1μ°¨ μΊμ λ§κ³ λ μ°κΈ° μ§μ° SQL μ μ₯μλΌλ κ²μ΄ μ‘΄μ¬ν©λλ€.
μ°κΈ° μ§μ° μ μ₯μλ SQLλ¬Έλ€μ λ€κ³ μλ€κ° νΈλμμ μ»€λ° μμ μ νλ²μ DBλ‘ μ²λ¦¬νκΈ° μν΄ μ¬μ©λ©λλ€.
INSERT λ¬Έμ κ°κ° λ°λ‘ νΈμΆνλ κ²κ³Ό, λͺ¨μμ batch insert νλ κ²μ μ°¨μ΄μΈ κ²μ΄μ£ .
μν°ν° κ°μ²΄λ₯Ό persist νλ©΄, 1μ°¨ μΊμμ μ μ₯λ¨κ³Ό λμμ ν΄λΉνλ INSERT λ¬Έμ΄ μ°κΈ° μ§μ° μ μ₯μμ λ±λ‘λ©λλ€.
λ§μ½ μ¬κΈ°μ λ€λ₯Έ μν°ν° κ°μ²΄λ₯Ό μΆκ°λ‘ persist νλ©΄, λκ°μ΄ 1μ°¨ μΊμμ μΆκ°λκ³ μ°κΈ° μ§μ° μ μ₯μμ INSERT λ¬Έμ΄ μΆκ°λ©λλ€.
κ·Έλ¦¬κ³ μ΅μ’ μ μΌλ‘ νΈλμμ μ»€λ° μμ μ΄ μ€λ©΄ μ°κΈ° μ§μ° μ μ₯μμ λͺ¨μλμλ SQLλ¬Έλ€μ νλ²μ DBλ‘ flush νκ² λ©λλ€.
μ€μ SQLλ¬Έλ€μ νΈλμμ μ»€λ° μμ μ νλ²μ λ λΌκ°κ² λλ κ²μ΄μ£ .
κ·Έλ λ€λ©΄ νλ²μ λͺκ°μ SQLλ¬Έμ μ²λ¦¬ν μ μλλμ λν κ²μ μλμ κ°μ΄ batch_size
μμ± μ€μ μ ν΅ν΄ κ΄λ¦¬ν μ μμ΅λλ€.
<property name="hibernate.jdbc.batch_size" value="10"/>
JPAμ κ°μ₯ ν° μ₯μ μ€ νλλ λ§μΉ μλ° μ»¬λ μ μ λ€λ£¨λ―μ΄ κ°μ²΄λ₯Ό λ€λ£° μ μλ€λ λΆλΆμ λλ€.
컬λ μ μ ν¬ν¨λ κ°μ²΄μ νλ κ°μ λ³κ²½ν λλ κ° λ³κ²½ μ΄ν λ€μ 컬λ μ μ λ£μ΄μ€ νμκ° μμ΅λλ€. κ°μ²΄μ μ°Έμ‘°κ°μ κ°μ§κ³ μκΈ° λλ¬Έμ κ΅³μ΄ λ€μ μ μ₯ν΄μ£Όλ κ³Όμ μ κ±°μΉ νμκ° μκΈ° λλ¬Έμ΄μ£ .
JPAμμλ λ§μ°¬κ°μ§λ‘ μν°ν° κ°μ²΄μ κ°μ λ³κ²½ν λ, κ°μ λ³κ²½ν λ€ λ€μ persist ν΄μ€ νμκ° μμ΅λλ€.
μλ° μ»¬λ μ μμ νλ κ² μ²λΌ setterλ₯Ό ν΅ν΄ κ°μ λ³κ²½νλ©΄ ν΄λΉ λ³κ²½ μ¬νμ μμμ κ°μ§ν©λλ€.
JPAλ μ΄λ° dirty checkingμ μ΄λ»κ² κ°λ₯νκ² ν κΉμ?
1μ°¨ μΊμμλ key, entityμ μ΅μ΄ μ½μ΄λ€μμ λΉμ μ€λ μ·μ΄ ν¨κ» ν¬ν¨λμ΄ μμ΅λλ€.
μ΄λ νΈλμμ 컀λ°μ μν flushκ° λ°μνλ©΄ μν°ν°μ μ€λ μ·μ λΉκ΅νμ¬ λ³κ²½λ κ°μ΄ μλμ§ νμΈν©λλ€.
λ§μ½ λ³κ²½λ λ΄μ©μ΄ μλ€λ©΄ UPDATE 쿼리λ₯Ό μ°κΈ° μ§μ° μ μ₯μμ μΆκ°ν©λλ€.
κ·Έλ° λ€ νΈλμμ μ΄ μ»€λ°λλ μμ μ μ°κΈ° μ§μ° μ μ₯μμ μλ 쿼리λ€κ³Ό κ°μ΄ flush ν©λλ€.
μ΄λ° dirty checking κΈ°λ₯μ΄ μ 곡λκΈ° λλ¬Έμ κ°λ°μκ° μ§μ UPDATE λ¬Έμ νμ μ 무λ₯Ό κ΅³μ΄ μ½λλ‘ νμΈν νμκ° μμ΄μ§κ² λλ κ²μ΄μ£ . (μ€μκ° μ€μ΄λλ ν¨κ³Όλ μκ² μ£ ?)
μ¬μ€ μμμ flushμ λν μ΄μΌκΈ°λ₯Ό μ΄λ―Έ νκ³ μμ΄μ flushμ λν λ΄μ©μ΄ λ¨Όμ μμ΄μΌ μ’μ§ μμλ μΆμ§λ§...
flushλ μμμ± μ»¨ν μ€νΈμ λ³κ²½λ΄μ©μ λ°μ΄ν°λ² μ΄μ€μ λ°μνλ κΈ°λ₯μ λλ€.
flushκ° λ°μνλ©΄ dirty checkingμ μ§ννκ³ , dirty checkingμ κ²°κ³Όμ λ°λΌ μμ λ μν°ν°μ λν SQLλ¬Έμ μ°κΈ° μ§μ° μ μ₯μμ λ±λ‘ν©λλ€. κ·Έλ¦¬κ³ μ΅μ’ μ μΌλ‘ μ°κΈ° μ§μ° μ μ₯μμ μλ 쿼리λ€μ λ°μ΄ν°λ² μ΄μ€μ 보λ λλ€.
κΈ°λ³Έμ μΌλ‘ flushλ νΈλμμ μ»€λ° μμ μ μλμΌλ‘ μ€νλμ§λ§, λ€λ₯Έ λ°©λ²λ€λ μ‘΄μ¬ν©λλ€.
μ€μ λ‘ μ΄λ κ² ν μΌμ λλ¬Όμ§λ§ em.flush()
λ₯Ό ν΅ν΄ μ§μ flush ν μ μμ΅λλ€.
λ§μ½ persistλ§ ν μνμμ 쿼리λ₯Ό μ§μ νμΈνκ³ μΆμ κ²½μ°μ μ¬μ©ν μ μμ΅λλ€.
μΆκ°λ‘, flushλ JPQL 쿼리λ₯Ό μ€νν μ μλμΌλ‘ νΈμΆλ©λλ€.
μ 리νμλ©΄,
flushλ μμμ± μ»¨ν μ€νΈμ μ΄λ€ λ³κ²½μ¬νμ μΌμΌν€μ§ μμ΅λλ€.
νΈλμμ μ»€λ° μ΄νμλ μμμ± μ»¨ν μ€νΈμ μλ©Έλ‘ μΈν΄ 1μ°¨ μΊμλ μ¬λΌμ§κ² λμ§λ§, flush κ° 1μ°¨ μΊμμ μ΄λ€ λ³κ²½μ¬νμ μΌμΌν€λ κ²μ μλλΌλ λ»μ λλ€.
flushλ μμμ± μ»¨ν μ€νΈμ λ³κ²½λ΄μ©μ DBμ λκΈ°νν΄μ£Όλ μν λ§ νλ κΈ°λ₯μ λλ€.
μμ μμμ± μ»¨ν μ€νΈ μλͺ μ£ΌκΈ°λ₯Ό μκ°νλ λΆλΆμμ κ°λ¨νκ² μΈκΈνμ§λ§,
μ€μμ μνλ κΈ°μ‘΄μ μμμ± μ»¨ν μ€νΈλ‘ κ΄λ¦¬λλ μν°ν° κ°μ²΄λ₯Ό λΆλ¦¬ν΄μ λ μ΄μ μμμ± μ»¨ν μ€νΈμ μν΄ κ΄λ¦¬λμ§ μλ μνλ₯Ό λ»ν©λλ€.
μ€μμ μνλ‘ λ§λλ λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
- em.detach(entity): νΉμ μν°ν°λ§ μ€μμ μνλ‘ μ ν
- em.clear(): μμμ± μ»¨ν μ€νΈ μ΄κΈ°ν
- em.close(): μμμ± μ»¨ν μ€νΈ μ’ λ£
μΈ λ°©λ² μ€ μ΄λ€ λ°©μμ μ¬μ©νλλΌλ μ€μμ μνλΌλ©΄ μμμ μ 리ν μμμ± μ»¨ν μ€νΈμ μ΄μ λ€μ μ΄μ©ν μ μκ² λ©λλ€.
μ΄μμΌλ‘ JPAμ ν΅μ¬μΈ μμμ± μ»¨ν μ€νΈμ λν μ 리λ₯Ό λ§μΉ©λλ€.