[JPA] μμμ± μ»¨ν μ€νΈμ λμμ리μ μ΄μ
π€ 미리 μ½κ³ μ€λ©΄ μ’μ κΈ
[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κ° νΈμΆλλ κ²½μ°
- entitymanager.flush(): κ°λ°μκ° μ§μ νΈμΆ
- tx.commit(): μλ μ€ν
- μ»€λ° μ μ μ₯μμ μλ SQLλ¬Έλ€μ flush νμ¬ μ€νμν¨ ν, DBμ λ°μνλ€.
- JPQL 쿼리 μ€ν: μλ μ€ν
- JPQLμ JPA λ§μΆ€ SQL 쿼리문μ΄λ€. JPQLμ EntityManagerκ° μ€ννλ μΏΌλ¦¬λ‘ νμ± λμ΄ SQLλ¬ΈμΌλ‘ λ³νλμ΄ μ°κΈ°μ§μ° SQL μ μ₯μμ μ μ₯λμ§ μκ³ λ°λ‘ DBμ μ€νλλ€.
λ°λΌμ μ΄μ μ μ°κΈ°μ§μ° SQL μ μ₯μμ μ μ₯νλ SQLλ¬Έλ€μ λ¨Όμ flush ν΄μΌ λ°μ΄ν°μ λ¬Έμ κ° μκΈ°μ§ μλλ€.
- JPQLμ JPA λ§μΆ€ SQL 쿼리문μ΄λ€. JPQLμ EntityManagerκ° μ€ννλ μΏΌλ¦¬λ‘ νμ± λμ΄ SQLλ¬ΈμΌλ‘ λ³νλμ΄ μ°κΈ°μ§μ° SQL μ μ₯μμ μ μ₯λμ§ μκ³ λ°λ‘ DBμ μ€νλλ€.
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