2 λΆ„ μ†Œμš”

JPA λ‚΄λΆ€ λ™μž‘ λ©”μ»€λ‹ˆμ¦˜

λ‹€μŒμ€ JPAλ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄ κ°€μž₯ μ€‘μš”ν•œ κ°œλ… 2κ°€μ§€λ‹€.

1. 객체와 κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ λ§€ν•‘
2. μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ(Persistence Context)

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλž€, μ—”ν‹°ν‹°λ₯Ό 영ꡬ μ €μž₯ν•˜λŠ” ν™˜κ²½μœΌλ‘œ, λˆˆμ— 보이지 μ•ŠλŠ” 논리적인 κ°œλ…μ΄λ‹€.
μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό ν†΅ν•΄μ„œ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ ‘κ·Όν•˜λŠ” 방식이닀.

엔티티와 μ—”ν‹°ν‹° λ§€λ‹ˆμ €

μ—”ν‹°ν‹°

  • μ—”ν‹°ν‹°(Entity)λŠ” DB에 μ‘΄μž¬ν•˜λŠ” ν•˜λ‚˜μ˜ Table을 클래슀둜 κ΅¬ν˜„ν•œ 것이닀.
  • μ—”ν‹°ν‹° 객체λ₯Ό 엔티티라고 ν•œλ‹€.

μ—”ν‹°ν‹° λ§€λ‹ˆμ €

  • μ—”ν‹°ν‹° λ§€λ‹ˆμ €(Entity Manager)λŠ” μ—”ν‹°ν‹°(객체)의 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•œλ‹€.
  • μ—”ν‹°ν‹° λ§€λ‹ˆμ €λŠ” μ—”ν‹°ν‹° 객체λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯ν•΄ κ΄€λ¦¬ν•œλ‹€.
  • 즉, 엔티티와 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ 사이에 μœ„μΉ˜ν•œλ‹€.

μ—”ν‹°ν‹°μ˜ 생λͺ…μ£ΌκΈ°?

μ—”ν‹°ν‹°μ˜ 생λͺ…주기에 따라 λΆ„λ₯˜ν•΄λ³Έλ‹€.

  1. λΉ„μ˜μ†
    • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ™€ μ „ν˜€ 관계가 μ—†λŠ” μƒˆλ‘œμš΄ μƒνƒœλ₯Ό λœ»ν•œλ‹€.
  2. μ˜μ†(managed)
    • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ κ΄€λ¦¬λ˜λŠ” μƒνƒœλ₯Ό λœ»ν•œλ‹€.
  3. μ€€μ˜μ†(detached)
    • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯λ˜μ—ˆλ‹€κ°€ λΆ„λ¦¬λœ μƒνƒœλ₯Ό λœ»ν•œλ‹€.
  4. μ‚­μ œ(removed)
    • 말 κ·ΈλŒ€λ‘œ μ‚­μ œλ₯Ό λœ»ν•œλ‹€.

image

λΉ„μ˜μ†

λΉ„μ˜μ† μƒνƒœλŠ” JPA에 관계 없이 객체만 μƒμ„±ν•˜λŠ” 단계이닀.

//객체λ₯Ό μƒμ„±ν•œ μƒνƒœ(λΉ„μ˜μ†) 
Member member = new Member(); 
member.setId("member1"); 
member.setUsername("νšŒμ›1");

μ˜μ†

μ˜μ† μƒνƒœλŠ” 객체λ₯Ό persist()λ₯Ό 톡해 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯ν•œ μƒνƒœμ΄λ‹€.

//객체λ₯Ό μƒμ„±ν•œ μƒνƒœ(λΉ„μ˜μ†) 
Member member = new Member(); 
member.setId("member1"); 
member.setUsername(β€œνšŒμ›1”);

// μ—”ν‹°ν‹° λ§€λ‹ˆμ € 호좜
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA이름");
좜처: https://devraphy.tistory.com/513 [개발자λ₯Ό ν–₯ν•˜μ—¬:ν‹°μŠ€ν† λ¦¬]
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

//객체λ₯Ό μ €μž₯ν•œ μƒνƒœ(μ˜μ†)
em.persist(member);

μ—¬κΈ°μ„œ μ£Όμ˜ν•΄μ•Όν•  뢀뢄이 μžˆλ‹€. μ˜μ† μƒνƒœκ°€ λ˜μ—ˆλ‹€κ³  ν•΄μ„œ κ³§λ°”λ‘œ DB에 μ €μž₯λ˜λŠ” 것은 μ•„λ‹ˆλ‹€!
그럼 μ–Έμ œ DB에 μ €μž₯될까? -> νŠΈλžœμž­μ…˜μ΄ commit을 ν•΄μ•Ό DB에 μ €μž₯λœλ‹€!

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ μž₯점

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ μž₯점은 λ‹€μŒκ³Ό κ°™λ‹€.

1. 1μ°¨ μΊμ‹œ

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—λŠ” 1μ°¨ μΊμ‹œλΌλŠ” 것이 μ‘΄μž¬ν•˜λŠ”λ°, 값이 μ‘΄μž¬ν•œλ‹€λ©΄ DB에 μ ‘κ·Όν•  ν•„μš” 없이 1μ°¨ μΊμ‹œμ—μ„œ μ‘°νšŒν•΄ 검색 속도λ₯Ό 높일 수 μžˆλ‹€.
λ§Œμ•½, 1μ°¨ μΊμ‹œμ— 값이 μ—†λ‹€λ©΄ DBμ—μ„œ μ‘°νšŒν•œ ν›„ ν•΄λ‹Ή 값을 1μ°¨ μΊμ‹œμ— μ €μž₯ν•˜κ³  λ°˜ν™˜ν•œλ‹€.
ν•˜μ§€λ§Œ 1μ°¨ μΊμ‹œλŠ” ν•œ νŠΈλžœμž­μ…˜ μ•ˆμ—μ„œλ§Œ μœ νš¨ν•˜κΈ° λ•Œλ¬Έμ— 큰 μ„±λŠ₯ ν–₯상을 κΈ°λŒ€ν•˜κΈ°λŠ” μ–΄λ ΅λ‹€.

2. 동일성(identity) 보μž₯

1μ°¨ μΊμ‹œλ‘œ 반볡 κ°€λŠ₯ν•œ 읽기(REPEATABLE READ) λ“±κΈ‰μ˜ νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€μ„ λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ•„λ‹Œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ°¨μ›μ—μ„œ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯이닀.

3. νŠΈλžœμž­μ…˜μ„ μ§€μ›ν•˜λŠ” μ“°κΈ° μ§€μ—°(transactional write-behind)

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—λŠ” 1μ°¨ μΊμ‹œκ°€ μ‘΄μž¬ν•˜μ§€λ§Œ, μ“°κΈ° μ§€μ—° SQL μ €μž₯μ†ŒλΌλŠ” 곳도 μ‘΄μž¬ν•œλ‹€.
κ°’ β€˜A’λ₯Ό persist()λ₯Ό 톡해 λ“±λ‘ν•˜λ©΄, 일단 1μ°¨ μΊμ‹œμ— μ €μž₯ν•˜κ³  JPAκ°€ κ°’ β€˜A’λ₯Ό 뢄석해 insert SQL을 μ“°κΈ° μ§€μ—° SQL μ €μž₯μ†Œμ— μ €μž₯ν•œλ‹€.
λ‹€λ₯Έ 값을 또 persistν•˜λ©΄, ν•΄λ‹Ή κ°’μ˜ SQL을 차곑차곑 μŒ“μ•„ μ˜¬λ¦°λ‹€.
μ΄λ ‡κ²Œ μŒ“μΈ SQL은 νŠΈλžœμž­μ…˜ commit μ‹œμ μ— DB에 μ €μž₯(flush)λœλ‹€.

4. λ³€κ²½ 감지(Dirty Checking)

Member member = em.find(Member.class, 150L);
member.setName("HELLO");

μœ„ μ½”λ“œκ°€ λ™μž‘ν•˜κ³  λ‚˜λ©΄, em.persit(member)와 같은 μ½”λ“œ μΆ”κ°€κ°€ ν•„μš”ν• κΉŒ?
κ²°λ‘ λΆ€ν„° 이야기 ν•˜λ©΄, ν•„μš” μ—†λ‹€.
JPA의 λͺ©μ μ— λŒ€ν•΄μ„œ 생각해볼 ν•„μš”κ°€ μžˆλ‹€.
JPAλŠ” 데이터λ₯Ό μžλ°” μ»¬λ ‰μ…˜(Collections)처럼 μ‚¬μš©ν•˜κΈ° μœ„ν•¨μΈλ°, μ»¬λ ‰μ…˜μ—μ„œ 데이터λ₯Ό μˆ˜μ •ν•œ 후에 λ‹€μ‹œ μ €μž₯ν•΄μ£ΌλŠ” μž‘μ—…μ΄ ν•„μš” ν–ˆμ—ˆλ‚˜?
μ»¬λ ‰μ…˜μ—μ„œλŠ” 그런 μž‘μ—…μ€ ν•„μš” μ—†μ—ˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ JPA도 μΆ”κ°€λ‘œ μ €μž₯ν•΄μ£ΌλŠ” μ½”λ“œλŠ” ν•„μš” μ—†λ‹€.
JPAλŠ” λ°μ΄ν„°λ² μ΄μŠ€ νŠΈλžœμž­μ…˜ 컀밋 μ‹œμ μ— 컀밋을 μˆ˜ν–‰ν•˜κ²Œ 되면 λ‚΄λΆ€μ μœΌλ‘œ flushκ°€ ν˜ΈμΆœλœλ‹€.
κ·Έ ν›„μ—λŠ” 엔티티와 μŠ€λƒ…μƒ·(SHAPSHOT)을 λΉ„κ΅ν•˜λŠ” λ™μž‘μ„ μˆ˜ν–‰ν•œλ‹€.
즉, 1μ°¨ μΊμ‹œ μ•ˆμ—λŠ” ID, Entity, SNAPSHOT(1μ°¨ μΊμ‹œμ— 값이 듀어왔을 λ•Œμ˜ 졜초 μ‹œμ ) 이 μ‘΄μž¬ν•œλ‹€.

5. μ§€μ—° λ‘œλ”©(Lazy Loading)

참고자료

[μΈν”„λŸ°]μžλ°” ORM ν‘œμ€€ JPA ν”„λ‘œκ·Έλž˜λ°(κΉ€μ˜ν•œ) - 기본편
https://devraphy.tistory.com/513

νƒœκ·Έ: ,

μΉ΄ν…Œκ³ λ¦¬:

μ—…λ°μ΄νŠΈ:

λŒ“κΈ€λ‚¨κΈ°κΈ°