Back-end

[JPA] μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ™μž‘μ›λ¦¬μ™€ 이점

μ„œμ±„λ¦¬ 2024. 2. 14. 08:40

🀭 미리 읽고 였면 쒋은 κΈ€

 

[JPA] JPA, Hibernate, Spring Data JPA에 λŒ€ν•œ μ΄λŸ°μ €λŸ°.. 정리

☁️ JPA μΈν„°νŽ˜μ΄μŠ€ 🫧 EntityManagerFactory JPA 섀정을 기반으둜 EntityManager μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” νŒ©ν† λ¦¬ μ—­ν•  (μ—¬λŸ¬ EntityManager 생성 κ°€λŠ₯) μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ DBλ₯Ό ν•˜λ‚˜λ§Œ μ‚¬μš©ν•˜λŠ” 경우 EntityManagerFactory

chaewsscode.tistory.com

 

[JPA] Hibernate JPA EntityManager 핡심 κΈ°λŠ₯

🌱 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ λ‚΄μ˜ Entity 생λͺ…μ£ΌκΈ° μ—”ν‹°ν‹°λŠ” 크게 4가지 μƒνƒœλ₯Ό 가지며, μƒνƒœλ₯Ό μ „ν™˜μ‹œν‚€λŠ” κΈ°λŠ₯을 EntityManagerκ°€ μ œκ³΅ν•œλ‹€. 1. Transient(λΉ„μ˜μ†): μ—”ν‹°ν‹° 객체가 Java λ©”λͺ¨λ¦¬μ—μ„œλ§Œ μ‘΄μž¬ν•˜κ³ ,

chaewsscode.tistory.com


1️⃣ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλž€?

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” μ—”ν‹°ν‹°λ₯Ό 영ꡬ μ €μž₯ν•˜λŠ” ν™˜κ²½μ„ λœ»ν•˜λ©° μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό λ°μ΄ν„°λ² μ΄μŠ€ μ‚¬μ΄μ—μ„œ 객체λ₯Ό λ³΄κ΄€ν•˜λŠ” κ°€μƒμ˜ λ°μ΄ν„°λ² μ΄μŠ€ 같은 역할을 ν•œλ‹€. μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό 톡해 μ—”ν‹°ν‹°λ₯Ό μ €μž₯ν•˜κ±°λ‚˜ μ‘°νšŒν•˜λ©΄ μ—”ν‹°ν‹° λ§€λ‹ˆμ €λŠ” μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ ν•œ 개λ₯Ό λ§Œλ“€μ–΄ μ—”ν‹°ν‹°λ₯Ό λ³΄κ΄€ν•˜κ³  κ΄€λ¦¬ν•œλ‹€.

em.persist(member); // "μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό μ΄μš©ν•΄ νšŒμ› μ—”ν‹°ν‹°λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯ν•œλ‹€"λŠ” 의미

 

2️⃣ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ™μž‘μ›λ¦¬

🌱 member μ—”ν‹°ν‹°λ₯Ό μΆ”κ°€ν•˜λŠ” κ³Όμ •

1. μ—”ν‹°ν‹°κ°€ μ˜μ†ν™”(persist)λ˜μ–΄ 1μ°¨ μΊμ‹œμ— μ €μž₯λœλ‹€.

2. 쓰기지연 SQL μ €μž₯μ†Œμ— INSERT문이 μƒμ„±λ˜μ–΄ 1μ°¨ μΊμ‹œμ— λ“±λ‘λœ 데이터λ₯Ό DB ν…Œμ΄λΈ”μ— μΆ”κ°€ν•  μ€€λΉ„λ₯Ό ν•œλ‹€.

3. flush λͺ…λ Ή μ‹œ 쓰기지연 SQL μ €μž₯μ†Œμ— μ €μž₯λ˜μ–΄ 있던 쿼리듀이 μ‹€ν–‰λ˜λ©΄μ„œ 1μ°¨ μΊμ‹œμ™€ DBκ°€ λ™κΈ°ν™”λœλ‹€.

4. λ§ˆμ§€λ§‰μœΌλ‘œ commitκΉŒμ§€ μ™„λ£Œλ˜λ©΄ 1μ°¨ μΊμ‹œμ˜ λ‚΄μš©μ΄ μ™„μ „νžˆ DB에 λ°˜μ˜λœλ‹€.

 

μœ„ μž‘μ—…μ€ λͺ¨λ‘ λ‹¨μΌν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μΌμ–΄λ‚œλ‹€.

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλž€ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μΌμ–΄λ‚˜λŠ” μž‘μ—…μ„ λͺ¨λ‘ κΈ°λ‘ν•˜λŠ” 곡간이며, λͺ¨λ“  μž‘μ—…μ€ μ–Έμ œλ“  ROLLBACK 될 수 μžˆλ‹€.

 

3️⃣ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ λ²”μœ„

νŠΈλžœμž­μ…˜μ΄ κ°™μœΌλ©΄, 같은 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.

 

νŠΈλžœμž­μ…˜ λ²”μœ„μ˜ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ μ „λž΅μ€ λ‹€μ–‘ν•œ μœ„μΉ˜μ—μ„œ μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό μ£Όμž…λ°›μ•„ μ‚¬μš©ν•˜λ”λΌλ„, λ™μΌν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œλŠ” 항상 같은 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.

@Repository
class Repo1 {
    @PersistenceContext EntityManager em;
    
    public void logic1(){
    	em.xxx(); // Repo1의 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ μ ‘κ·Ό
    }
}


@Repository
class Repo2 {
    @PersistenceContext EntityManager em;
    
    public void logic2(){
    	em.xxx(); // Repo2의 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ μ ‘κ·Ό
    }
}

 

μœ„μ™€ 같은 μƒν™©μ—μ„œ μ•„λž˜ logic()을 μ‹€ν–‰ν•˜λŠ” 상황을 예둜 λ“€λ©΄

@Service
class MainService{
    @Autowired Repo1 repo1;
    @Autowired Repo2 repo2;
    
    @Transctional
    public void logic(){
    	repo1.logic1();
        repo2.logic2(); 
    }
}

 

repo1κ³Ό repo2의 μ—”ν‹°ν‹° λ§€λ‹ˆμ €λŠ” λ‹€λ₯΄μ§€λ§Œ, 같은 νŠΈλžœμž­μ…˜μ΄κΈ° λ•Œλ¬Έμ— 같은 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.

 

그리고 ν•΄λ‹Ή μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” νŠΈλžœμž­μ…˜κ³Ό 생λͺ…μ£ΌκΈ°κ°€ λ™μΌν•˜λ‹€.


νŠΈλžœμž­μ…˜μ΄ λ‹€λ₯΄λ©΄, λ‹€λ₯Έ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.

μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆλŠ” μŠ€λ ˆλ“œλ§ˆλ‹€ 각각 λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ„ ν• λ‹Ήν•˜κΈ° λ•Œλ¬Έμ— 같은 μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό μ‚¬μš©ν•΄λ„ λ‹€λ₯Έ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.

λ”°λΌμ„œ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈκ°€ μŠ€λ ˆλ“œ 간에 κ³΅μœ λ˜μ§€ μ•ŠμœΌλ―€λ‘œ λ©€ν‹°μŠ€λ ˆλ“œ 상황에 μ•ˆμ „ν•˜λ‹€.

 

4️⃣ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 이점

  • 1μ°¨ μΊμ‹œ
  • 동일성 보μž₯
  • λ³€κ²½ 감지(Dirty Checking)
  • μ“°κΈ° 지연
  • 지연 λ‘œλ”©

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

🌱 member μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•˜λŠ” κ³Όμ •

1. EntityManagerκ°€ 쑰회(find)λ₯Ό μš”μ²­ν•œλ‹€.

2. 1μ°¨ μΊμ‹œμ—μ„œ μš°μ„ μ μœΌλ‘œ 데이터λ₯Ό μ°Ύκ³  μ›ν•˜λŠ” 데이터가 μ—†λŠ” 경우 DB SELECT문을 μ‹€ν–‰ν•˜μ—¬ μ‘°νšŒν•œλ‹€.

3. μ‘°νšŒν•œ κ²°κ³Όλ₯Ό 1μ°¨ μΊμ‹œμ— μ €μž₯ν•˜κ³  μ—”ν‹°ν‹° 객체λ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜(return)ν•œλ‹€.

 

이후 단일 νŠΈλžœμž­μ…˜μ—μ„œ 같은 μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•  경우 1μ°¨ μΊμ‹œμ—μ„œ λ°”λ‘œ μ—”ν‹°ν‹° μ‘°νšŒκ°€ κ°€λŠ₯ν•˜λ‹€.

μ΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 접근을 쀄여 μ„±λŠ₯을 ν–₯μƒμ‹œν‚¨λ‹€.

 

2) 동일성 보μž₯

1μ°¨ μΊμ‹œλŠ” flushκ°€ μˆ˜ν–‰λ˜μ§€ μ•ŠλŠ” 이상 DB와 λ™κΈ°ν™”λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 1μ°¨ μΊμ‹œμ— μ‘΄μž¬ν•˜λŠ” μ—”ν‹°ν‹°λŠ” μ–Έμ œλ‚˜ λ™μΌν•œ 엔티티이닀.

Member findMember1 = em.find(Member.class, 10L);
Member findMember2 = em.find(Member.class, 10L);

System.out.println("findMember = " + (findMember1 == findMember2));

 

λ”°λΌμ„œ 같은 νŠΈλžœμž­μ…˜ μ•ˆμ—μ„œ == 비ꡐ μ‹œ λ™μΌν•œ μ°Έμ‘°κ°€ λ‚˜μ™€ trueλ₯Ό λ°˜ν™˜ν•œλ‹€.

 

3) μ“°κΈ° 지연

μœ„μ˜ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ™μž‘ μ›λ¦¬μ—μ„œ μ„€λͺ…ν–ˆλ“―이 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” 쓰기지연 SQL μ €μž₯μ†Œλ₯Ό κ°€μ Έ SQL문이 μƒμ„±λ˜μ–΄λ„ λ°”λ‘œ μ‹€ν–‰λ˜μ§€ μ•Šκ³  μ €μž₯λœλ‹€. λ”°λΌμ„œ μž¦μ€ I/O λ°œμƒμ„ 막을 수 μžˆλ‹€.

또, μ›ν•˜λŠ” μ‹œμ μ— κ°œλ°œμžκ°€ SQL문을 μ‹€ν–‰ν•  수 μžˆλ„λ‘ flush κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

 

πŸ€” flushκ°€ ν˜ΈμΆœλ˜λŠ” 경우

  1. entitymanager.flush(): κ°œλ°œμžκ°€ 직접 호좜
  2. tx.commit(): μžλ™ μ‹€ν–‰
    • 컀밋 μ „ μ €μž₯μ†Œμ— μžˆλŠ” SQL문듀을 flush ν•˜μ—¬ μ‹€ν–‰μ‹œν‚¨ ν›„, DB에 λ°˜μ˜ν•œλ‹€.
  3. JPQL 쿼리 μ‹€ν–‰: μžλ™ μ‹€ν–‰
    • JPQL은 JPA 맞좀 SQL 쿼리문이닀. JPQL은 EntityManagerκ°€ μ‹€ν–‰ν•˜λŠ” 쿼리둜 νŒŒμ‹± λ˜μ–΄ SQL문으둜 λ³€ν™˜λ˜μ–΄ 쓰기지연 SQL μ €μž₯μ†Œμ— μ €μž₯λ˜μ§€ μ•Šκ³  λ°”λ‘œ DB에 μ‹€ν–‰λœλ‹€.
      λ”°λΌμ„œ 이전에 쓰기지연 SQL μ €μž₯μ†Œμ— μ €μž₯ν–ˆλ˜ SQL문듀을 λ¨Όμ € flush ν•΄μ•Ό 데이터에 λ¬Έμ œκ°€ 생기지 μ•ŠλŠ”λ‹€.

 

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

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” 1μ°¨ μΊμ‹œμ— μ €μž₯된 μ—”ν‹°ν‹°μ˜ 처음 μƒνƒœλ₯Ό μŠ€λƒ…μƒ·μœΌλ‘œ λ§Œλ“€μ–΄ μ €μž₯ν•œλ‹€.

 

🌱 member μ—”ν‹°ν‹°λ₯Ό μˆ˜μ •ν•˜λŠ” κ³Όμ •

1. κ°œλ°œμžκ°€ find()둜 μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•œλ‹€.

2. κ°œλ°œμžκ°€ ν•΄λ‹Ή μ—”ν‹°ν‹°λ₯Ό setter ν•¨μˆ˜λ‘œ ν•„λ“œ 데이터λ₯Ό λ³€κ²½ν–ˆλ‹€.

❗️ 처음 μƒνƒœμ˜ μŠ€λƒ…μƒ·κ³Ό λ™μΌν–ˆλ˜ 과거와 달리, λ”λŸ½ν˜€μ‘Œλ‹€.(Dirty)

 

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” 초기 μƒνƒœλ₯Ό μ €μž₯ν•œ μŠ€λƒ…μƒ·κ³Ό μ—”ν‹°ν‹°λ₯Ό λΉ„κ΅ν•˜μ—¬ μ–Όλ§ˆλ‚˜ λ”λŸ¬μ›Œμ‘ŒλŠ”μ§€λ₯Ό μ²΄ν¬ν•˜λŠ”λ°, 이λ₯Ό Dirty Checking 즉, 변경감지라 λΆ€λ₯Έλ‹€.

변경이 κ°μ§€λ˜λ©΄ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” μžλ™μœΌλ‘œ UPDATE문을 μƒμ„±ν•˜μ—¬ 쓰기지연 SQL μ €μž₯μ†Œμ— μ €μž₯ν•œλ‹€.

κ°œλ°œμžλŠ” λ‹¨μˆœνžˆ ν•„λ“œ λ°μ΄ν„°λ§Œ λ³€κ²½ν•œ 것인데 μžλ™μœΌλ‘œ UPDATEλ¬ΈκΉŒμ§€ μƒμ„±λ˜μ–΄ μ†μ‰¬μš΄ 개발이 κ°€λŠ₯해진닀.

 

5) 지연 λ‘œλ”©(Lazy Loading)

🌱 μ¦‰μ‹œ λ‘œλ”©(Eager Loading)

μ—°κ΄€ 관계 λ§€ν•‘μ˜ fetch 속성을 FetchType.EAGER둜 지정해 μ—”ν‹°ν‹° 쑰회 μ‹œ μ—°κ΄€λœ μ—”ν‹°ν‹°λ₯Ό ν•¨κ»˜ μ‘°νšŒν•œλ‹€.

 

public class Member {
    ...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TEAM_ID")    
    private Team team;
}
SELECT 
	...
FROM 
	MEMBER M LEFT OUTER JOIN TEAM T
		ON M.TEAM_ID=T.TEAM_ID
WHERE
	M.MEMBER_ID="id"

 

ν•˜μ΄λ²„λ„€μ΄νŠΈλŠ” μ¦‰μ‹œ λ‘œλ”©μ„ μ΅œμ ν™”ν•˜κΈ° μœ„ν•΄ κ°€λŠ₯ν•˜λ©΄ 쑰인 쿼리λ₯Ό 톡해 μ—°κ΄€ μ—”ν‹°ν‹°λ₯Ό ν•œ λ²ˆμ— μ‘°νšŒν•œλ‹€.

μ΄λ•Œ, μ‹€ν–‰λ˜λŠ” SQL은 μ™ΈλΆ€ 쑰인(LEFT OUTER JOIN)을 μ‚¬μš©ν•œλ‹€. (νšŒμ›μ€ νŒ€μ΄ 없을 수 μžˆμ–΄ NULL값을 ν—ˆμš©ν•˜κΈ° λ•Œλ¬Έ)

 

ν•˜μ§€λ§Œ μ„±λŠ₯ μ΅œμ ν™”μ—μ„œλŠ” λ‚΄λΆ€ 쑰인(INNER JOIN)이 μœ λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— @JoinColumn(nullable = false)λ₯Ό μ‚¬μš©ν•˜λ©΄ λ‚΄λΆ€ 쑰인을 μ‚¬μš©ν•  수 μžˆλ‹€.

 

🌱 지연 λ‘œλ”©(Lazy Loading)

μ—°κ΄€ 관계 λ§€ν•‘μ˜ fetch 속성을 FetchType.LAZY둜 지정해 μ—°κ΄€λœ μ—”ν‹°ν‹°λ₯Ό μ‹€μ œλ‘œ μ‚¬μš©ν•  λ•Œ μ‘°νšŒν•œλ‹€.

 

@Entity
public class Member {
    ...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")    
    private Team team;
}

 

νšŒμ› 쑰회 μ‹œ λ°”λ‘œ νŒ€μ„ μ‘°νšŒν•˜μ§€ μ•Šκ³ , team 멀버 λ³€μˆ˜μ— ν”„λ‘μ‹œ 객체(κ°€μ§œ 객체)λ₯Ό λ„£μ–΄λ‘”λ‹€.

κ·Έ ν›„ team의 μ‹€μ œ 데이터가 ν•„μš”ν•œ μˆœκ°„μ— DBλ₯Ό μ‘°νšŒν•΄ ν”„λ‘μ‹œ 객체λ₯Ό μ‘°νšŒν•œλ‹€.

λ§Œμ•½ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— 객체가 이미 μ‘΄μž¬ν•  경우 ν”„λ‘μ‹œ 객체가 μ•„λ‹Œ μ‹€μ œ 객체λ₯Ό μ‚¬μš©ν•œλ‹€.

 

μΆ”μ²œν•˜λŠ” 방법은 λͺ¨λ“  연관관계에 지연 λ‘œλ”©μ„ μ‚¬μš©ν•˜λŠ” κ²ƒμ΄μ§€λ§Œ 지연 λ‘œλ”©μ΄ 항상 쒋은 것은 μ•„λ‹ˆλ‹€.

λ§Œμ•½ νŒ€κ³Ό νšŒμ›μ„ 항상 ν•¨κ»˜ μ‚¬μš©ν•œλ‹€λ©΄ μ²˜μŒλΆ€ν„° ν•œ λ²ˆμ— κ°€μ Έμ˜€λŠ” 것이 효율적이기 λ•Œλ¬Έμ— 상황에 맞게 μ„ νƒν•˜λŠ” 것이 μ’‹λ‹€.

λ”°λΌμ„œ 개발 μ™„λ£Œ 단계에 왔을 λ•Œ, μ‹€μ œ μ‚¬μš© 상황을 보며 μ΅œμ ν™”ν•˜λŠ” 것이 μ’‹λ‹€.

 

 

 

 

 

[JPA] ν”„λ‘μ‹œ, μ¦‰μ‹œ λ‘œλ”©κ³Ό μ§€μ—°λ‘œλ”©

ν”„λ‘μ‹œ μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•˜κ³  항상 μ—°κ΄€λœ μ—”ν‹°ν‹°κ°€ μ‚¬μš©λ˜λŠ” 것은 μ•„λ‹ˆλ‹€. νšŒμ›μ„ μ‘°νšŒν–ˆλ‹€κ³  해도 νšŒμ›μ΄ κ°€μž…ν•œ νŒ€μ„ μ‚¬μš©ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€. λ•Œλ¬Έμ— νšŒμ›μ„ μ‘°νšŒν•  λ•Œ 항상 νŒ€ μ—”ν‹°ν‹°λ₯Ό ν•¨κ»˜

girawhale.tistory.com

 

[JPA] μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 이점 ( + DirtyChecking )

[JPA] JPA λ™μž‘μ›λ¦¬ ( μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ ) [JPA] νŒ¨λŸ¬λ‹€μž„μ˜ 뢈일치 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ κ°œλ°œμ€ 주둜 객체지ν–₯μ–Έμ–΄λ‘œ 이루어진닀. 객체지ν–₯μ–Έμ–΄λŠ” ν˜„μ‹€μ˜ λ§Žμ€ 문제λ₯Ό μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜μ§€λ§Œ λ¬Έμ œκ°€ μžˆλ‹€. 데이

lordofkangs.tistory.com

 

[JPA] OSIV λž€?

μŠ€ν”„λ§μ—μ„œ JPAλ₯Ό μ‚¬μš©ν•˜κ²Œ 되면 μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ νŠΈλžœμž­μ…˜κ³Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό κ΄€λ¦¬ν•΄μ£Όλ―€λ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ†μ‰½κ²Œ κ°œλ°œν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹Ήμ—°ν•˜κ²Œλ„ μ΄λŸ¬ν•œ JPA의 λ‚΄λΆ€ λ™μž‘μ›λ¦¬λ₯Ό λͺ¨λ₯΄κ³ 

ttl-blog.tistory.com

 

νŠΈλžœμž­μ…˜ λ²”μœ„μ˜ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ

μˆœμˆ˜ν•˜κ²Œ J2SE ν™˜κ²½μ—μ„œ JPAλ₯Ό μ‚¬μš©ν•˜λ©΄ κ°œλ°œμžκ°€ 직접 μ—”ν‹°ν‹° λ§€λ‹ˆμ €λ₯Ό μƒμ„±ν•˜κ³  νŠΈλžœμž­μ…˜λ„ 관리해야 ν•œλ‹€. ν•˜μ§€λ§Œ μŠ€νŠΈλ§μ΄λ‚˜ J2EE μ»¨ν…Œμ΄λ„ˆ ν™˜κ²½μ—μ„œ JPAλ₯Ό μ‚¬μš©ν•˜λ©΄ μ»¨ν…Œμ΄λ„ˆκ°€ μ œκ³΅ν•˜λŠ” μ „λž΅

devbksheen.tistory.com