BULK

XingXi·2024년 1월 8일
0

JPA

목록 보기
23/23
post-thumbnail

🍕 Reference

자바 ORM 표준 JPA 프로그래밍 : 교보문고
자바 ORM 표준 JPA 프로그래밍 - 기본편 : 인프런

벌크 연산

Query 한 번으로 다수의 Entity 변경
JPA 의 Dirty Checking 만으로 다수의 ROW 를 변경하기에는 많은 수의 SQL QUERY가 발생

사용 예시

Member

@Entity
public class Member
{
    @Id @GeneratedValue
    private Long id;
    private String username;

    private int age;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    @Embedded
    private Address address;

    @Enumerated(EnumType.STRING)
    private MemberType memberType;

Main

            int resultCnt = em.createQuery("update Member m set m.age = 20").executeUpdate();
            System.out.println(resultCnt);

Result

Hibernate: 
    /* update
        Member m 
    set
        m.age = 20 */ update
            Member 
        set
            age=20
3

executeUpdate(); 의 결과로 영향 받은 ROW 의 개수가 출력
executeUpdate(); 발생 시 FLUSH 자동 호출 됨

주의

영속성 컨텍스트를 무사하고 DB에 직접 Query

  • 벌크연산을 실행한 하거나
  • 벌크 연산을 수행하고 나서 영속성 컨텍스트를 한번 더 초기화 함

영속성 컨텍스트 초기화 필요성

main

            try
        {
            Address address = new Address("1","1","1");

            Team teamA = new Team();
            teamA.setName("A");
            em.persist(teamA);

            Team teamB = new Team();
            teamB.setName("B");
            em.persist(teamB);

            Member member1 = new Member();
            member1.setUsername("회원1");
            member1.setAge(203);
            member1.setTeam(teamA);
            member1.setAddress(address);
            member1.setMemberType(MemberType.ADMIN);
            em.persist(member1);

            Member member2 = new Member();
            member2.setUsername("회원2");
            member2.setAge(210);
            member2.setTeam(teamA);
            member2.setAddress(address);
            member2.setMemberType(MemberType.ADMIN);
            em.persist(member2);

            Member member3 = new Member();
            member3.setUsername("회원3");
            member3.setAge(120);
            member3.setTeam(teamB);
            member3.setAddress(address);
            member3.setMemberType(MemberType.ADMIN);
            em.persist(member3);

            int resultCnt = em.createQuery("update Member m set m.age = 20").executeUpdate();
            System.out.println(resultCnt);
            System.out.println("member1.getAge() : "+member1.getAge());
            System.out.println("member2.getAge() : "+member2.getAge());
            System.out.println("member3.getAge() : "+member3.getAge());

결과

Hibernate: 
    /* update
        Member m 
    set
        m.age = 20 */ update
            Member 
        set
            age=20
3
member1.getAge() : 203
member2.getAge() : 210
member3.getAge() : 120

DB 에는 member 들의 나이가 20 으로 수정되어 있지만, 초기화 되지 않아 영속성 컨텍스트안의 member들의 나이가 20 이 아니다.

main

            int resultCnt = em.createQuery("update Member m set m.age = 20").executeUpdate();
            em.clear();
            member1 = em.find(Member.class, member1.getId());
            member2 = em.find(Member.class, member2.getId());
            member3 = em.find(Member.class, member3.getId());
            System.out.println(resultCnt);
            System.out.println("member1.getAge() : "+member1.getAge());
            System.out.println("member2.getAge() : "+member2.getAge());
            System.out.println("member3.getAge() : "+member3.getAge());

결과

member1.getAge() : 20
member2.getAge() : 20
member3.getAge() : 20

결론

벌크연산을 수행하면 영속성 컨텍스트를 초기화 해야한다.

0개의 댓글