Framework/Spring Framework

JPA μ—”ν‹°ν‹° μƒνƒœ (생λͺ…μ£ΌκΈ°)

ν”„λ‘œκ·Έλž˜λ¨Έ μ˜€μ›” 2024. 6. 6.

JPA의 μ—”ν‹°ν‹° μƒνƒœ

  • Transient: μ—”ν‹°ν‹°κ°€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μƒνƒœμ΄λ‹€. μƒˆλ‘œμš΄ μ—”ν‹°ν‹° 객체λ₯Ό μƒμ„±ν•˜μ§€λ§Œ 아직 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μΆ”κ°€λ˜μ§€ μ•Šμ•˜λ‹€.
User user = new User();
user.setName("John Doe");
// userλŠ” transient μƒνƒœ
  • Persistent: μ—”ν‹°ν‹°κ°€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ κ΄€λ¦¬λ˜λŠ” μƒνƒœμ΄λ‹€. 이 μƒνƒœμ—μ„œλŠ” μ—”ν‹°ν‹°μ˜ λ³€κ²½ 사항이 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ μΆ”μ λ˜κ³ , νŠΈλžœμž­μ…˜μ΄ 컀밋될 λ•Œ λ°μ΄ν„°λ² μ΄μŠ€μ— λ°˜μ˜λœλ‹€.
entityManager.persist(user);
// userλŠ” persistent μƒνƒœ
  • Detached: μ—”ν‹°ν‹°κ°€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ 더 이상 κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μƒνƒœμ΄λ‹€. 주둜 νŠΈλžœμž­μ…˜μ΄ μ’…λ£Œλ˜κ±°λ‚˜ μ—”ν‹°ν‹° λ§€λ‹ˆμ €κ°€ λ‹«νž λ•Œ λ°œμƒν•œλ‹€.
entityManager.detach(user);
// userλŠ” detached μƒνƒœ
  • Removed: μ—”ν‹°ν‹°κ°€ μ‚­μ œλ˜κΈ°λ‘œ ν‘œμ‹œλœ μƒνƒœμ΄λ‹€. remove λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ—”ν‹°ν‹°λ₯Ό μ œκ±°ν•œλ‹€. νŠΈλžœμž­μ…˜μ΄ 컀밋될 λ•Œ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ‚­μ œλœλ‹€.
entityManager.remove(user);
// userλŠ” removed μƒνƒœ

μ˜ˆμ‹œ

μ—”ν‹°ν‹° 클래슀

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_name", nullable = false)
    private String name;
    
    private int age;

    // getters and setters
}

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ μ‚¬μš© μ˜ˆμ‹œ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class JpaMain {
    public static void main(String[] args) {
        // μ•„μ§κΉŒμ§€λŠ” ν•΄λ‹Ή μ—”ν‹°ν‹°λ₯Ό μ—”ν‹°ν‹° λ§€λ‹ˆμ €κ°€ κ΄€λ¦¬ν•˜μ§€ μ•ŠλŠ”λ‹€.
        User user = new User();
        user.setName("John Park");
        user.setAge(30);
        
        //META-INF/persistence.xmlμ—μ„œ μ΄λ¦„이 db인 persistence-unit을 μ°Ύμ•„μ„œ μ—”ν‹°ν‹° λ§€λ‹ˆμ € νŒ©ν† λ¦¬λ₯Ό μƒμ„± 
        EntityManagerFatory emf = Persistence.createEntityManagerFactory("db");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        
        try {
            // μ—”ν‹°ν‹° λ§€λ‹ˆμ €μ—μ„œ μˆ˜ν–‰ν•˜λŠ” λͺ¨λ“  λ‘œμ§μ€ νŠΈλžœμž­μ„  μ•ˆμ—μ„œ μˆ˜ν–‰λΌμ•Ό ν•œλ‹€.
            tx.begin();
            
            // μ΄λ ‡κ²Œ ν•˜λ©΄ ν•΄λ‹Ή μ—”ν‹°ν‹° λ§€λ‹ˆμ €μ˜ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μœ„μ—μ„œ λ§Œλ“  User κ°μ²΄κ°€ μ €μž₯λœλ‹€.  
            // μ΄μ œ user μ—”ν‹°ν‹°λŠ” μ—”ν‹°ν‹° λ§€λ‹ˆμ €μ˜ κ΄€λ¦¬ λŒ€μƒμ΄ λ˜κ³ , μ˜μ†μ„±μ„ κ°€μ‘Œλ‹€κ³  λ§ν•  μˆ˜ μžˆλ‹€.
            em.persist(user);
            
            // μƒνƒœ λ³€κ²½ κ°μ§€ (Dirty Checking)
            user.setName("Jane Park");
 
               // Detached μƒνƒœ
            em.detach(user);
 
            // λ‹€μ‹œ Persistent μƒνƒœλ‘œ λ³€κ²½
            em.merge(user);
            
            // νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•œλ‹€. DB둜 flushκ°€ μΌμ–΄λ‚˜λ©΄μ„œ DB에 λ°μ΄ν„°κ°€ μ˜μ†λœλ‹€.
            tx.commit();
        } catch(Exception e) {
            // μ–΄λ–€ μ΄μœ μ—μ„œ μ˜€λ₯˜κ°€ λ‚¬λ‹€λ©΄ νŠΈλžœμž­μ…˜μ„ λ‘€λ°± μ‹œμΌœμ€˜μ•Όν•œλ‹€.
            tx.rollback();
        } finally {
            // μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό μ’…λ£Œμ‹œμΌœμ€˜μ•Ό ν•œλ‹€.  
            em.close();
        }
        emf.close(); // λ§ˆμ°¬κ°€μ§€λ‘œ μ—”ν‹°ν‹° λ§€λ‹ˆμ € νŒ©ν† λ¦¬λ„ λ”이상 μ“°μ§€ μ•ŠλŠ”λ‹€λ©΄ μ’…λ£Œμ‹œμΌœμ€˜μ•Ό ν•œλ‹€.
    }
}
cs

 

μš”μ•½

  • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ(Persistence Context): μ—”ν‹°ν‹° λ§€λ‹ˆμ €κ°€ κ΄€λ¦¬ν•˜λŠ” μ—”ν‹°ν‹° μΈμŠ€ν„΄μŠ€λ“€μ˜ μ§‘ν•©μœΌλ‘œ, μ—”ν‹°ν‹°μ˜ 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜κ³  1μ°¨ μΊμ‹œ 및 λ³€κ²½ 감지 κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.
  • μ—”ν‹°ν‹° μƒνƒœ: Transient(μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μƒνƒœ), Persistent(μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ κ΄€λ¦¬λ˜λŠ” μƒνƒœ), Detached(μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ˜ν•΄ 더 이상 κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μƒνƒœ), Removed(μ‚­μ œλœ μƒνƒœ)둜 κ΅¬λΆ„λœλ‹€.

μ°Έκ³ 

μΈν”„λŸ° - μžλ°” ORM ν‘œμ€€ JPA ν”„λ‘œκ·Έλž˜λ° - 기본편 / κΉ€μ˜ν•œ

λŒ“κΈ€