์˜์†์„ฑ ๊ด€๋ฆฌ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ 2๊ฐ€์ง€์ด๋‹ค.

  • ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ„์˜ ๋งคํ•‘
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ( JPA ๋‚ด๋ถ€ ๋™์ž‘ )

EntityManagerFactory์™€ EntityManager

ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ์˜ฌ๋•Œ ๋งˆ๋‹ค ( ์ฆ‰, thread๊ฐ€ ํ•˜๋‚˜์”ฉ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค ) EntityManager๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

EntityManager๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ DB ์ปค๋„ฅ์…˜ ํ’€์„ ์‚ฌ์šฉํ•ด์„œ DB์— ์ ‘๊ทผํ•œ๋‹ค.

EntityManagerFactory

JPA๋Š” EntityManagerFactory๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋กœ๋”ฉ๋˜๋Š” ์‹œ์ ์— DB๋‹น ๋”ฑ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("emf");

๊ทธ๋ฆฌ๊ณ  WAS๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” ์‹œ์ ์— EntityManagerFactory๋ฅผ ๋‹ซ๋Š”๋‹ค.

EntityManager

์‹ค์ œ ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„๊ฐ€ ์ˆ˜ํ–‰๋  ๋•Œ๋งˆ๋‹ค ์ƒ์„ฑ๋œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ ์ƒ์„ฑํ–ˆ๋‹ค๊ฐ€ ์š”์ฒญ์ด ๋๋‚˜๋ฉด ๋‹ซ๋Š”๋‹ค.

thread๊ฐ„์— ๊ณต์œ ๋ฅผ ํ•˜๋ฉด ์•ˆ๋˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜ํ–‰๋œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ๋‹ซ๊ณ  DB ์ปค๋„ฅ์…˜์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

public void createMember() {
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();

    tx.begin();

    Member member = new Member("Id", "pw");
    em.persist(member);

    tx.commit();
}

EntityTransaction

๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ๋ฐ˜๋“œ์‹œ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค. ( ์กฐํšŒ๋Š” ์ƒ๊ด€ ์—†์Œ )

EntityTransaction tx = entityManager.getTransaction();

tx.begin(); // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
tx.commit(); // ํŠธ๋žœ์žญ์…˜ ์ˆ˜ํ–‰
tx.rollback(); // ์ž‘์—…์— ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ

๊ด€๊ณ„๋„๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™๋‹ค.

EntityManager ๊ด€๊ณ„๋„ - ์ถœ์ฒ˜ : https://iyoungman.github.io/jpa/EntityManagerFactory-EntityManager-PersistenceContext/

EntityManager๋Š” DB ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•œ ์‹œ์ ์— ์ปค๋„ฅ์…˜ ํ’€์—์„œ ์ปค๋„ฅ์…˜์„ ํ•˜๋‚˜ ์–ป๋Š”๋‹ค.

JPA์˜ ๊ตฌํ˜„์ฒด( ex. hibernate )๋“ค์€ EntityManagerFactory๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ปค๋„ฅ์…˜ ํ’€์„ ๋งŒ๋“ ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ( Persistence Context )

Entity๋ฅผ ์˜๊ตฌ ์ €์žฅํ•˜๋Š” ํ™˜๊ฒฝ์„ ๋œปํ•œ๋‹ค.

EntityManager๋กœ Entity๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์กฐํšŒํ•˜๋ฉด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— Entity๋ฅผ ๋ณด๊ด€ํ•˜๊ณ  ๊ด€๋ฆฌํ•œ๋‹ค.

em.persist(entity);

์œ„ ์ฝ”๋“œ๋Š” ์‹ค์ œ๋กœ DB์— ์ €์žฅํ•œ๋‹ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด์„œ Entity๋ฅผ ์˜์†ํ™”ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

์ฆ‰, Entity๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

EntityManager๋ฅผ ํ†ตํ•ด์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•˜๊ฒŒ ๋œ๋‹ค.

package javax.persistence;

import java.util.List;
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.metamodel.Metamodel;

public interface EntityManager {
    void persist(Object var1);

    <T> T merge(T var1);

    void remove(Object var1);

    <T> T find(Class<T> var1, Object var2);

    <T> T find(Class<T> var1, Object var2, Map<String, Object> var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3, Map<String, Object> var4);

    <T> T getReference(Class<T> var1, Object var2);

    void flush();

    ...
   }

EntityManager๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด 1:1๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์˜ JPA์—์„œ๋Š” ์—ฌ๋Ÿฌ EntityManager๊ฐ€ ํ•˜๋‚˜์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋œ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์˜ JPA๋ผ ํ•จ์€ ๋ฌด์—‡์ผ๊นŒ?

์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ™˜๊ฒฝ (ex. spring)์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ EntityManager๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ปจํ…Œ์ด๋„ˆ์— ์œ„์ž„ํ•œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์Šคํ”„๋ง์€ ์‹ฑ๊ธ€ํ†ค ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†์„ฑ๊ฐ’์€ ๋ชจ๋“  thread๊ฐ€ ๊ณต์œ ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ž˜์„œ ์—ฌ๋Ÿฌ thread๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” EntityManager์˜ Thread-safe๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณด์žฅํ• ๊นŒ?

EntityManager๋ฅผ Proxy๋ฅผ ํ†ตํ•ด์„œ ๊ฐ์‹ธ๊ณ  EntityManager ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ๋•Œ ๋งˆ๋‹ค Proxy๋ฅผ ํ†ตํ•ด์„œ EntityManager๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

EntityManager๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” @PersistenceContext๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

  • ์ง์ ‘ ์ƒ์„ฑํ•œ EntityManager์— @PersistenceContext๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒฝ์šฐ
@Service
public class TestService {

    @PersistenceContext
    private EntityManager entityManager;

    ...
}
entityManager = {$Proxy84@9656} "Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4f356b98]"

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ดˆ๊ธฐํ™” ๋˜๋ฉด์„œ @PersistenceContext ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ฃผ์ž…๋ฐ›์€ EntityManager๋ฅผ Proxy๋กœ ๊ฐ์‹ผ๋‹ค.

SharedEntityManagerCreator์— ์˜ํ•ด Proxy๋กœ ๋งŒ๋“ค์–ด์ง„๋‹ค.

  • SimpleJpaRepository์˜ EntityManager
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

    private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";

    private final JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager em;
    private final PersistenceProvider provider;

    private @Nullable CrudMethodMetadata metadata;
    private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;

    ...
}
em = {$Proxy84@9748} "Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4f356b98]"

SharedEntityManagerCreator์— ์˜ํ•ด Proxy๋กœ ๋งŒ๋“ค์–ด์ง„๋‹ค.

ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์ „๋žต์„ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘ํ•  ๋•Œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋๋‚  ๋•Œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋๋‚ธ๋‹ค.

์ฆ‰, ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์œผ๋ฉด ๊ฐ™์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ - ์ถœ์ฒ˜ : https://iyoungman.github.io/jpa/EntityManagerFactory-EntityManager-PersistenceContext/

์—ฌ๋Ÿฌ EntityManager๋ฅผ ์‚ฌ์šฉํ•ด๋„ ํ•œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์ด๋ฉด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณต์œ ํ•œ๋‹ค.

์ถœ์ฒ˜ : https://iyoungman.github.io/jpa/EntityManagerFactory-EntityManager-PersistenceContext/

๊ฐ™์€ EntityManager๋ฅผ ์‚ฌ์šฉํ•ด๋„ ํŠธ๋žœ์žญ์…˜์— ๋”ฐ๋ผ ์ ‘๊ทผํ•˜๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋‹ค๋ฅด๋‹ค.

๋”ฐ๋ผ์„œ ๊ฐ™์€ EntityManager๋ฅผ ํ˜ธ์ถœํ•ด๋„ ์ ‘๊ทผํ•˜๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•œ๋‹ค.

์ถœ์ฒ˜ : https://iyoungman.github.io/jpa/EntityManagerFactory-EntityManager-PersistenceContext/

Entity์˜ ์ƒ์„ฑ์ฃผ๊ธฐ ( Entity LifeCycle )

  • ๋น„์˜์† ( new / transient )

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€๋Š” ์ „ํ˜€ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ์ƒํƒœ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ๋งŒ ํ•œ ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

Member member = new Member();
member.setId("memberID");
member.setPw("password");
  • ์˜์† ( managed )

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋œ ์ƒํƒœ๋กœ Entity๊ฐ€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

Member member = new Member();
member.setId("memberID");
member.setPw("password");

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();

tx.begin();

em.persist(member); // ์˜์† ์ƒํƒœ๊ฐ€ ๋œ๋‹ค๊ณ  ๋ฐ”๋กœ ์ฟผ๋ฆฌ๊ฐ€ ๋‚ ๋ผ๊ฐ€์ง€๋Š” ์•Š์Œ

//tx.commit(); ์„ ํ•ด์ฃผ์–ด์•ผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” ์ •๋ณด๋“ค์ด DB์— ์ฟผ๋ฆฌ๋กœ ๋‚ ๋ผ๊ฐ
  • ์ค€์˜์† ( detached )

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์—ˆ๋‹ค๊ฐ€ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์ง€์šด ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

em.detach(member);
  • ์‚ญ์ œ ( removed )

์‹ค์ œ DB ์‚ญ์ œ๋ฅผ ์š”์ฒญํ•œ ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

em.remove(member);

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

1. 1์ฐจ ์บ์‹œ

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด๋ถ€์—๋Š” 1์ฐจ ์บ์‹œ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ( 1์ฐจ ์บ์‹œ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ผ๊ณ  ์ดํ•ดํ•ด๋„ ๋œ๋‹ค. )

Map<Key, Value> ํ˜•ํƒœ๋กœ 1์ฐจ ์บ์‹œ์— ์ €์žฅ์ด ๋œ๋‹ค. ( key = @Id๋กœ ์„ ์–ธํ•œ PK, value = ํ•ด๋‹น Entity ์ž์ฒด )

Member member = new Member();
member.setId("memberID");
member.setPw("password");
/* ์˜์† ์ƒํƒœ (Persistence Context ์— ์˜ํ•ด Entity ๊ฐ€ ๊ด€๋ฆฌ๋˜๋Š” ์ƒํƒœ) */
// DB ์ €์žฅ X, 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋จ
em.persist(member); 
// 1์ฐจ ์บ์‹œ์—์„œ ์กฐํšŒ
Member findMember = em.find(Member.class, "memberID"); 

1์ฐจ ์บ์‹œ์— Entity๊ฐ€ ์žˆ์„ ๋•Œ ์ด์ ์€ ๋ฌด์—‡์ผ๊นŒ?

em.find()๋ฅผ ํ•˜๋ฉด DB๋ณด๋‹ค ๋จผ์ € 1์ฐจ ์บ์‹œ๋ฅผ ์กฐํšŒํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  1์ฐจ ์บ์‹œ์— ํ•ด๋‹น Entity๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

1์ฐจ ์บ์‹œ์— ํ•ด๋‹น Entity๊ฐ€ ์—†๋‹ค๋ฉด DB๋ฅผ ์ง์ ‘ ์กฐํšŒํ•˜๊ณ  ์กฐํšŒํ•œ ๊ฒฐ๊ณผ๋ฅผ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•œ ํ›„ Entity๋ฅผ ์ฐพ์•„์˜จ๋‹ค.

EntityManager๋Š” ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„๋กœ ๋งŒ๋“ค๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋๋‚  ๋•Œ ํ•จ๊ป˜ ์ข…๋ฃŒ๊ฐ€ ๋œ๋‹ค.

๊ทธ๋•Œ 1์ฐจ ์บ์‹œ๋„ ๋ชจ๋‘ ๋‚ ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜ํ–‰๋˜๋Š” ๋™์•ˆ์—๋งŒ ์ด๋“์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํฐ ์„ฑ๋Šฅ ์ด์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋Š” ์•Š๋‹ค.

ํ•˜์ง€๋งŒ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๊ต‰์žฅํžˆ ๋ณต์žกํ•œ ๊ฒฝ์šฐ์—๋Š” ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

2. ๋™์ผ์„ฑ ๋ณด์žฅ

Member member1 = entityManager.find(Member.class, "member1");
Member member2 = entityManager.find(Member.class, "member1");
System.out.println(member1 == member2); // ๋™์ผ์„ฑ ๋น„๊ต true

์˜์† Entity์˜ ๋™์ผ์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

member1์— ํ•ด๋‹นํ•˜๋Š” Entity๋ฅผ 2๋ฒˆ ์กฐํšŒํ•˜๊ฒŒ ๋˜๋ฉด 1์ฐจ ์บ์‹œ์— ์˜ํ•ด ๊ฐ™์€ Reference๋กœ ์ธ์‹์ด ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๊ฐ™์€ Entity๋ฅผ ๋น„๊ตํ•˜๊ฒŒ ๋˜๋ฉด ๋™์ผ์„ฑ์€ ๋ณด์žฅ๋œ๋‹ค.

1์ฐจ ์บ์‹œ๋กœ Repeatable read ๋“ฑ๊ธ‰์˜ isolation level์„ DB๊ฐ€ ์•„๋‹Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฐจ์›์—์„œ ์ œ๊ณตํ•œ๋‹ค.

3. Entity ๋“ฑ๋ก ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ ( ๋ฒ„ํผ๋ง )

public void createMember() {
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();

    //EntityManager๋Š” ํ…Œ์ดํ„ฐ ๋ณ€๊ฒฝ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
    tx.begin();

    Member member1 = new Member("Id1", "pw1");
    Member member2 = new Member("Id2", "pw2");

    //์ด๋•Œ๊นŒ์ง€ Insert ์ฟผ๋ฆฌ๋ฅผ DB์— ๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค.
    em.persist(member1);
    em.persist(member2);

    //commit ํ•˜๋Š” ์ˆœ๊ฐ„ DB์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ธ๋‹ค.
    tx.commit();
}

em.persist()

JPA๊ฐ€ insert SQL์„ ๊ณ„์† ์Œ“๊ณ  ์žˆ๋Š” ์ƒํƒœ๋‹ค.

member1์„ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•œํ›„ JPA๊ฐ€ Entity๋ฅผ ๋ถ„์„ํ•˜์—ฌ insert SQL์„ ๋งŒ๋“ ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ insert SQL์„ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ๋ผ๋Š” ๊ณณ์— ์Œ“๊ณ  DB์— ๋ฐ”๋กœ ๋„ฃ์ง€ ์•Š๊ณ  ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

member2๋„ ๊ฐ™์€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

tx.commit()

commit ์‹œ์ ์— insert SQL์„ ๋™์‹œ์— DB๋กœ ๋ณด๋‚ธ๋‹ค.

์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์Œ“์—ฌ์žˆ๋Š” SQL๋“ค์„ DB๋กœ ๋‚ ๋ฆฐ๋‹ค. ( flush() )

flush()๋Š” 1์ฐจ ์บ์‹œ๋ฅผ ์ง€์šฐ์ง€๋Š” ์•Š๊ณ  ์ฟผ๋ฆฌ๋“ค์„ DB์— ๋‚ ๋ ค์„œ DB์™€์˜ ์‹ฑํฌ๋ฅผ ๋งž์ถ”๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

flush() ํ›„์—๋Š” ์‹ค์ œ DB ํŠธ๋žœ์žญ์…˜์— ์ปค๋ฐ‹์ด ๋œ๋‹ค. ( commit() )

4. ๋”ํ‹ฐ ์ฒดํ‚น ( Dirty Checking )

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();

tx.begin();

// ์˜์† ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ
Member memberA = em.find(Member.class, "memberA");

// ์˜์† ์—”ํ‹ฐํ‹ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ •
memberA.setUsername("hi");
memberA.setAge(10);

//ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹
tx.commit();

Entity ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์ปค๋ฐ‹ํ•˜๊ธฐ ์ „์— update()๋‚˜ persist()๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด๋‹ฌ๋ผ๊ณ  ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•˜์ง€ ์•Š์„๊นŒ?

๊ทธ๋Ÿด ํ•„์š” ์—†๋‹ค.

Entity ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์ •ํ•˜๊ณ  commit๋งŒ ํ•˜๋ฉด DB์— ์ž๋™์œผ๋กœ ๋ฐ˜์˜์ด ๋œ๋‹ค.

์ฆ‰, ๋ฐ์ดํ„ฐ๊ฐ€ setํ•˜๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜์—ฌ ์ž๋™์œผ๋กœ update SQL์ด ๋‚˜๊ฐ€๋Š” ๊ฒƒ์ด๋‹ค.

tx.commit()์„ ํ•˜๋ฉด flush()๊ฐ€ ์ผ์–ด๋‚  ๋•Œ Entity์™€ ์Šค๋ƒ…์ƒท์„ ์ผ์ผ์ด ๋น„๊ตํ•œ๋‹ค.

๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด update SQL์„ ๋งŒ๋“ค๊ณ  ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์ €์žฅ์„ ํ•œ๋‹ค.

update SQL์„ DB์— ๋ฐ˜์˜ํ•œ ํ›„ commit()์„ ํ•˜๊ฒŒ ๋œ๋‹ค.

@DynamicUpdate
๋”ํ‹ฐ ์ฒดํ‚น์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” update SQL์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
@DynamicUpdate๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ€๊ฒฝ๋œ ํ•„๋“œ๋งŒ ๋ฐ˜์˜๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

5. Entity ์‚ญ์ œ

Member memberA = em.find(Member.class, "memberA");

em.remove(memberA);

์œ„์˜ Entity ์ˆ˜์ • ๋งค์ปค๋‹ˆ์ฆ˜๊ณผ ๋™์ผํ•˜๋‹ค.

ํŠธ๋žœ์žญ์…˜์˜ commit ์‹œ์ ์— delete SQL์ด ๋‚˜๊ฐ„๋‹ค.