πŸƒJPA μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ

Spring JPA

2 minute read

EntityManager와 EntityManager Factory

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ

  • JPAλ₯Ό μ΄ν•΄ν•˜λŠ”λ° κ°€μž₯ μ€‘μš”ν•œ μš©μ–΄μ΄λ‹€.
  • μ—”ν‹°ν‹°λ₯Ό 영ꡬ μ €μž₯ν•˜λŠ” ν™˜κ²½μ΄λΌλŠ” λœ»μ΄λ‹€.

EntityManager.persist(entity);

  • μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό ν†΅ν•΄μ„œ μ ‘κ·Όν•  수 μžˆλ‹€.

JPA Entity의 생λͺ…μ£ΌκΈ°

  • λΉ„μ˜μ† μƒνƒœ : JPAκ°€ κ΄€λ¦¬ν•˜μ§€ μ•ŠλŠ” κ·Έλƒ₯ μžλ°” 객체이닀.
    //객체λ₯Ό μƒμ„±ν•œ μƒνƒœ(λΉ„μ˜μ†)  
     Member member = new Member();  
     member.setId("member1");  
     member.setUsername("νšŒμ›1");   
    
  • μ˜μ† μƒνƒœ : κ·Έλ ‡λ‹€λ©΄ 이건 관리
    ```java
    //객체λ₯Ό μƒμ„±ν•œ μƒνƒœ(λΉ„μ˜μ†)
    Member member = new Member();
    member.setId(β€œmember1”);
    member.setUsername(β€œνšŒμ›1”);
    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    //객체λ₯Ό μ €μž₯ν•œ μƒνƒœ(μ˜μ†)
    em.persist(member);

// ν˜Ήμ€ JPAμ—μ„œ μ–»μ–΄μ˜¨ 객체(find λ“±)

  
무엇이 μ˜μ†μƒνƒœμΈκ°€λ₯Ό μ•Œμˆ˜μžˆλŠ”κ²ƒμ΄ μ€‘μš”ν•˜λ‹€. λ‚˜μ€‘μ— κ°œλ…μ„ 톡해 μ œλŒ€λ‘œ μ΄ν•΄ν•΄λ³΄μž.  
  
- μ€€μ˜μ†μƒνƒœ : μ˜μ†μƒνƒœμ˜€λ‹€κ°€ λΆ„λ¦¬λœ μƒνƒœ  
em.detach(member);  
  
- μ‚­μ œ  
em.remove(member);  
  
  
  
## μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 이점  
- 1μ°¨ μΊμ‹œ  
- 사싀 νŠΈλžœμž­μ…˜ ν•˜λ‚˜ λ‚΄μ—μ„œμ˜ μΊμ‹œμ΄λ―€λ‘œ λΉ„μ§€λ‹ˆμŠ€ 둜직이 μ—„μ²­λ‚˜κ²Œ ν¬μ§€μ•Šλ‹€λ©΄ μ„±λŠ₯μƒμ˜ 이점은 λ³„λ‘œ μ—†μ§€λ§Œ, μ˜μ† μƒνƒœλ₯Ό κ΅¬ν˜„ν•˜λŠ”λ° κ°€μž₯ 결정적인 μš”μ†Œμ΄λ‹€. 사싀상 1μ°¨ μΊμ‹œλ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλΌκ³  봐도 λœλ‹€.  
  
- μš”μ•½ν•΄μ„œ μ„€λͺ…ν•˜λ©΄, μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—λŠ” 1μ°¨ μΊμ‹œλΌλŠ” 곳이 μ‘΄μž¬ν•΄μ„œ 이λ₯Ό 톡해 μ‹€μ œλ‘œ 쿼리가 λ‚˜κ°ˆμ§€ μ•ˆλ‚˜κ°ˆμ§€κ°€ κ²°μ •λœλ‹€.  
  
![](https://develup4.github.io/bear_to_github_blog_template/assets/images/a6471f68dd43774a8d934c26af4bd148/jpa-basic-pdf%20%E1%84%91%E1%85%A9%E1%86%AF%E1%84%83%E1%85%A5%20%E1%84%8B%E1%85%A7%E1%86%AF%E1%84%80%E1%85%B5%203.png)  
μœ„ 그림처럼 ν˜„μž¬ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” 객체듀은 1μ°¨ μΊμ‹œμ— λ³΄κ΄€λ˜μ–΄ 있으며, findλ₯Ό 톡해 객체λ₯Ό μ°Ύμ•˜μ„λ•Œ μΊμ‹œμ— μ‘΄μž¬ν•œλ‹€λ©΄ μ‹€μ œλ‘œ μΏΌλ¦¬λŠ” λ‚˜κ°€μ§€ μ•ŠλŠ”λ‹€.  
  
  
![](https://develup4.github.io/bear_to_github_blog_template/assets/images/a6471f68dd43774a8d934c26af4bd148/jpa-basic-pdf%20%E1%84%91%E1%85%A9%E1%86%AF%E1%84%83%E1%85%A5%20%E1%84%8B%E1%85%A7%E1%86%AF%E1%84%80%E1%85%B5%204.png)  
반면 μΊμ‹œμ— μ—†λŠ” 객체 μ°ΎλŠ”λ‹€λ©΄ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‘°νšŒν•˜κ²Œ 되고, μ–»μ–΄μ˜¨ 값은 λ°˜ν™˜λ˜λ©° λ™μ‹œμ— μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— 보관도 λœλ‹€. λ‹€μŒμ— μ°ΎλŠ” 일이 μžˆλ‹€λ©΄ μΊμ‹œμ—μ„œ 해결될 것이닀.  
  
뒀에 μ„€λͺ…에 λ‚˜μ˜€κ² μ§€λ§Œ μ΄λŸ¬ν•œ κ²½μš°μ—λ„ 쿼리가 λ°”λ‘œ λ‚˜κ°€λŠ” 것은 μ•„λ‹ˆλ‹€. flushλ˜λŠ” μ‹œμ μ€ λ’€μ—μ„œ μ„€λͺ…ν•œλ‹€.  
  
- μ˜μ†μ—”ν‹°ν‹°μ˜ 동일성 보μž₯  
```java  
Member a = em.find(Member.class, "member1");  
 Member b = em.find(Member.class, "member1");  
 System.out.println(a == b); //동일성 비ꡐ true  

μœ„ μ½”λ“œμ—μ„œ 보듯 λ¬Έμ œμ‚¬ν•­μ΄μ—ˆλ˜ 동일성도 보μž₯λœλ‹€. 1μ°¨ μΊμ‹œκ°€ 반볡 κ°€λŠ₯ν•œ 읽기(Repeatable Read)λ₯Ό μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
=> νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€μ„ λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ•„λ‹Œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ°¨μ›μ—μ„œ 제곡

  • νŠΈλžœμž­μ…˜μ„ μ§€μ›ν•˜λŠ” μ“°κΈ° μ§€μ—°

μ•„κΉŒ μ„€λͺ…ν–ˆλ˜ 쿼리가 μ‹€μ œλ‘œ λ‚˜κ°€λŠ” μ‹œμ μ΄λ‹€. flash()κ°€ ν˜ΈμΆœλ λ•Œ μ‹€μ œλ‘œ 쿼리가 λ‚˜κ°€μ§€λ§Œ, νŠΈλžœμž­μ…˜μ΄ commitλ λ•Œ flushκ°€ μΌμ–΄λ‚˜λ―€λ‘œ 사싀상 이 μ‹œμ μ— ν˜ΈμΆœλœλ‹€.

μœ„ 그림처럼 μΊμ‹œμ— 연산이 μΌμ–΄λ‚ λ•Œλ§ˆλ‹€ ν•„μš”ν•œ 쿼리가 μ €μž₯μ†Œμ— μ €μž₯됐닀가 λ‚˜κ°€λ―€λ‘œ 쿼리λ₯Ό ν•œλ²ˆμ— λ²„νΌλ§ν•΄μ„œ λ‚ λ¦¬λŠ” μ„±λŠ₯μƒμ˜ 이점도 μžˆλ‹€(μ„€μ •μ—μ„œ λ²„νΌμ˜ 크기도 μ •ν•  수 μžˆλ‹€)

  • λ³€κ²½ 감지(Dirty Checking)
    EntityManager em = emf.createEntityManager();  
     EntityTransaction transaction = em.getTransaction();  
     transaction.begin(); // [νŠΈλžœμž­μ…˜] μ‹œμž‘  
     // μ˜μ† μ—”ν‹°ν‹° 쑰회  
     Member memberA = em.find(Member.class, "memberA");  
     // μ˜μ† μ—”ν‹°ν‹° 데이터 μˆ˜μ •  
     memberA.setUsername("hi");  
     memberA.setAge(10);  
     //em.update(member) 이런 μ½”λ“œκ°€ μžˆμ–΄μ•Ό ν•˜μ§€ μ•Šμ„κΉŒ? <========== μš”λΆ€λΆ„ μ€‘μš”  
     transaction.commit(); // [νŠΈλžœμž­μ…˜] 컀밋  
    

μ˜μ†μ„± κ°μ²΄λŠ” λ”°λ‘œ λͺ…령없이 객체만 λ³€κ²½λ˜μ–΄λ„ 변경사항이 λ°μ΄ν„°λ² μ΄μŠ€μ— μ μš©λœλ‹€. 이λ₯Ό 더티체킹이라고 ν•œλ‹€. μ›λ¦¬λŠ” μœ„μ²˜λŸΌ μŠ€λƒ…μƒ·κ³Όμ˜ 비ꡐλ₯Ό 톡해 μ—…λ°μ΄νŠΈ 쿼리가 μžλ™μœΌλ‘œ μƒμ„±λ˜λŠ” ν˜•μ‹μ΄λ‹€.

무엇인 μ˜μ†μ„± 객체인지λ₯Ό μž˜μ΄ν•΄ν•˜λ©΄ 객체 μˆ˜μ • μ΄μ™Έμ˜ λ™μž‘μ€ ν•„μš”ν•˜μ§€ μ•Šλ‹€.

Flush()

  • em.flush() : λ³„λ‘œμ“ΈμΌμ€ μ—†λ‹€.
  • νŠΈλžœμž­μ…˜ 컀밋
  • JPQL 쿼리싀행
    em.persist(memberA);  
    em.persist(memberB);  
    em.persist(memberC);  
     //쀑간에 JPQL μ‹€ν–‰  
     query = em.createQuery("select m from Member m", Member.class);  
     List<Member> members= query.getResultList();  
    

μ œλŒ€λ‘œ jpql이 μˆ˜ν–‰λ˜λ €λ©΄ 이전 κ²°κ³Όκ°€ λ°˜μ˜λ˜μ–΄ μžˆμ–΄μ•Όν•˜λ―€λ‘œ

  • μ΄λ¦„λ•Œλ¬Έμ— ν—·κ°ˆλ¦¬μ§€ 말자. SQLμ €μž₯μ†Œκ°€ ν”ŒλŸ¬μ‹œλ˜λŠ” 것이닀. μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” μœ μ§€λœλ‹€.
  • clear()에 μ˜ν•΄μ„œ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈκ°€ 사라진닀.

μ€€μ˜μ†μƒνƒœκ°€ λ˜λŠ”λ²•

  • em.detach(entity)
  • em.clear()
  • em.close()

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 수λͺ…

μ•„κΉŒ 1μ°¨ μΊμ‹œμ˜ μ„±λŠ₯μƒμ˜ 이점은 λ³„λ‘œ μ—†λ‹€κ³  λ§ν•œκ²ƒμ΄, νŠΈλžœμž­μ…˜μ΄ λλ‚˜λ©΄ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” μ‚­μ œλœλ‹€(이거 λ§žλŠ”μ§€ 확인)