당우 일기장

플러시 본문

JPA

플러시

당우 2025. 4. 8. 19:05

한줄요약

 메모리에 쌓인 변화를 DB에 "저장"

 

 

 

 

플러시란?
JPA에서 영속성 컨텍스트(Persistence Context)에 있는 변경된 데이터를 데이터베이스에 반영하는 과정
 

JPA에서 플러시는 영속성 컨텍스트에 있는 엔티티의 변경 사항(INSERT, UPDATE, DELETE 등)을 데이터베이스에 동기화하는 작업을 말해. 영속성 컨텍스트는 엔티티를 관리하는 메모리 공간인데, 여기서 변경된 내용은 바로 DB에 반영되지 않아. 플러시가 호출되어야 SQL 쿼리가 만들어지고 DB에 실제로 적용돼.

플러시는 몇 가지 상황에서 발생해:

  1. 명시적 플러시: entityManager.flush()를 직접 호출할 때.
  2. 자동 플러시: 트랜잭션이 커밋(commit)되거나, 쿼리 실행 전에 자동으로 발생할 수 있어.                                                  (예: FlushModeType.AUTO 설정)
  3. 필요 시점: JPA가 데이터 일관성을 위해 쿼리 실행 전에 변경 사항을 DB에 반영해야 할 때.

예를 들어, 엔티티를 수정한 뒤 쿼리로 조회하려는데 수정된 데이터가 안 보인다면? 플러시가 안 돼서 영속성 컨텍스트와 DB가 동기화되지 않은 거야. 단, 플러시는 커밋과 다르게 트랜잭션을 끝내진 않아. 그냥 중간에 DB에 반영만 하는 거지.

 

예제코드

엔티티를 수정한 뒤 플러시를 명시적으로 호출해서 DB에 반영하는 상황

import javax.persistence.*;

public class JpaFlushExample {
    public static void main(String[] args) {
        // 1. EntityManagerFactory 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            // 2. 트랜잭션 시작
            tx.begin();

            // 3. 새로운 엔티티 생성 및 저장
            Member member = new Member();
            member.setId(1L);
            member.setName("홍길동");
            em.persist(member);

            // 4. 엔티티 수정
            member.setName("김영희");
            System.out.println("플러시 전: 영속성 컨텍스트에만 반영됨");

            // 5. 명시적 플러시 호출
            em.flush();
            System.out.println("플러시 후: DB에 반영됨");

            // 6. 트랜잭션 커밋
            tx.commit();
            System.out.println("커밋 완료: 모든 변경 사항 확정");
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            em.close();
        }
        emf.close();
    }
}

// 엔티티 클래스
@Entity
@Table(name = "MEMBER")
class Member {
    @Id
    private Long id;
    private String name;

    // Getter, Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

코드 설명

  1. 엔티티 생성 및 저장: Member 객체를 만들어 persist로 영속성 컨텍스트에 넣어.
  2. 수정: setName으로 이름을 "홍길동"에서 "김영희"로 바꿔. 이 시점에선 영속성 컨텍스트에만 반영되고 DB엔 아직 안 써져.
  3. 플러시 호출: em.flush()를 호출하면 영속성 컨텍스트의 변경 사항(INSERT 후 UPDATE)이 DB에 반영돼. 여기선 "김영희"가 DB에 저장됨.
  4. 커밋: 트랜잭션을 커밋하면 모든 작업이 확정돼.

예상 출력

플러시 전: 영속성 컨텍스트에만 반영됨
(여기서 실제 SQL이 DB로 날아감: INSERT 후 UPDATE)
플러시 후: DB에 반영됨
커밋 완료: 모든 변경 사항 확정

추가 참고사항

persistence.xml 파일이 필요해. 기본 설정은 아래처럼 하면 돼:
<persistence-unit name="my-persistence-unit">
    <class>Member</class>
    <properties>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test"/>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
</persistence-unit>