포스트

update2

Update

  • JPA에서 값을 데이터베이스와 영속시키기 위한 몇가지 방법이 있다.
  • 그중 하나가 merge 방법이다
  1. merge 방법
    • findbyid로 값을 가져온 뒤 영속을 시켜둔 상태에서 필요시마다 save 메소드를 날리면서 id값 기준으로 동일한 값이 있는지 체킹하고
    • update가 없다면 insert를 날려주는 방식이다.
    • 하지만 이러한 방법은 매번 쿼리를 날릴 때마다 select insert / select update를 날리게 된다
    • 이것은 불필요한 데이터 베이스 체킹이 한번씩 날라가는 것이다.
    • 이러한 것을 방지하기 위한것이 더티체킹이다
  2. 더티체킹
    • 디비에 왔다 갔다 하는 방법을 맨 처음 영속할 때 한 번, 그리고 모든 프로세스가 종료될 때 한번 이렇게 두 번만 하는 것이다.
    • 이것을 위해서는 해당 메서드에 @Transactional 어노테이션으로 묶어줘야 한다
    • 그러면 jpa는 1차 캐싱 부분에 값을 계속 저장하고 변경하면서 마지막 commit 시점에 flush를 날려준다고 생각하면 된다
    • 만약 엔티티의 컬럼이 너무 많을 경우에는 update를 필요하고 변경된 부분만 날릴 수 있는데 이 방법은 entity class에 @DynamicUpdate라는 어노테이션을 추가해주면 된다.
1
2
3
4
5
6
public String testJpa(String id){
  Optional<TestTable> enttList = repo.findById(id);
  TestTable dto = enttList.get();
  dto.setFctr1("40");
  System.out.println("++++++++");
}
  • 위의 함수를 테스트 해보자
    1. 현재 코드 그대로 테스트
    1. 현재 코드에서 @Transactional 어노테이션만 추가 후 테스트
    1. 현재코드에서 System 출력 이전과 이후에 각각 repository.save(dto); 코드를 추가해서 save 함수 집어넣기
  • 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public String testJpa(String id){
  Optional<TestTable> enttList = repo.findById(id);
  TestTable entity = enttList.get();
  entity.setFctr1("40");
  System.out.println("++++++++");
}

// ++++++++ 만 출력. 코드 update 안됨
// save 저장도 없고 Transactional로 묶이지 않아 아무리 엔티티가 변했다해도 쿼리가 날아가지 않고 종료된다

@Transactional
public String testJpa(String id){
  Optional<TestTable> enttList = repo.findById(id);
  TestTable entity = enttList.get();
  entity.setFctr1("40");
  System.out.println("++++++++");
}

// ++++++++ 후 update query 전송.
// Transactional로 묶여 있기 때문에 묶인 메서드가 종료될 때 commit이 일어나기 때문에 종료 직전 ++++를 찍고 update가 이뤄진다

public String testJpa(String id){
  Optional<TestTable> enttList = repo.findById(id);
  TestTable entity = enttList.get();
  entity.setFctr1("40");
  repository.save(entity);
  System.out.println("++++++++");
}

// update query 전송 후 ++++ 출력

public String testJpa(String id){
  Optional<TestTable> enttList = repo.findById(id);
  TestTable entity = enttList.get();
  entity.setFctr1("40");
  System.out.println("++++++++");
  repository.save(entity);
}

// ++++ 출력 후 update query 전송

// 3번과 4번의 경우 일단 entity는 setter를 쓰는 것을 지양한다. 하지만 편의상 했다.
// Transactional 로 묶여있지는 않지만 실제로 commit을 위한 쿼리를 날리는 save 함수를 직접 호출했기에 결과가 위와 같다