본문 바로가기

프로그래밍/JPA

JPA_더티체킹(dirty checking)

더티 체킹 

: 더티 체킹(dirty checking)은 JPA에서 영속성(persistence) 컨텍스트가 관리하는 엔티티 객체의 변경 사항을 감지하는 매커니즘이다.

 

영속성 컨텍스트는 엔티티를 수정하면 엔티티의 상태를 자동으로 감지하고, 수정된 상태를 데이터베이스에 자동으로 반영한다. 이를 더티 체킹이라고 한다. 

즉, 더티 체킹은 상태 변경 검사이다.

 

JPA에서는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 데이터베이스에서 자동으로 반영해준다. (commit 처리)

 

 

 

User.java

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
@Entity
@Data // ! 주의 ! Object Mapper가 파싱 처리할 때, setter가 반드시 있어야 함.
public class User {
 
    // 기본키 매핑
    @Id // pk 설정
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    @Column(nullable = falselength = 30)
    private String username;
    
    @NotBlank // null, "" - 빈 문자열을 잡겠다.
    @Column(nullable = falselength = 100)
    private String password;
    
    @NotBlank
    @Column(nullable = falselength = 50)
    private String email;
    
    @CreationTimestamp // 자동 시간 입력 now()
    private Timestamp createdDate;
    
    @ColumnDefault("'user'"// default - 문자열 타입이라고 명시는 ''(홑따옴표)
    private String role; // 데이터의 범주화 : user, admin, manager
 
}
cs

 

 

DummyControllerTest.java

eamil, password 수정 처리 로직 구현 

1번 방식 : 기존 로직 처리 (save 처리)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// JSON으로 던질 예정
// 기존 로직 처리 (save 처리)
@PutMapping("/dummy/user/{id}")
public User updateUser(@Validated @PathVariable Integer id, @RequestBody User reqUser) {
    // 수정을 하려면 존재 여부 확인부터 해야 함.
    // 영속화 된 데이터
    User userEntity = userRepository.findById(id).orElseThrow(() -> {
        return new IllegalArgumentException("해당 유저가 존재하지 않습니다.");
    });
    
    // 클라이언트가 던진 데이터
    // reqUser
    userEntity.setEmail(reqUser.getEmail());
    userEntity.setPassword(reqUser.getPassword());
    
    userRepository.save(userEntity);
    
    return userEntity;
}
cs

 

 

2번 방식 : 더티 체킹 (dirty checking) 사용

1
2
3
4
5
6
7
8
9
10
11
12
@Transactional
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable Integer id, @Validated @RequestBody User userReq) {
    User userEntity = userRepository.findById(id).orElseTrhow(() -> {
        return new IllegalArgumentException("해당 유저가 존재하지 않습니다.");
    });
    
    userEntity.setEmail(reqUser.getEmail());
    userEntity.setPassword(reqUser.getPassword());
    
    return userEntity;
}
cs

dirty checking 사용 (트랜잭션이 끝나면 자동으로 save 함.)

 save를 호출하지 않아도 변경 처리 됨. 

트랜잭션 내에서 트랜잭션이 끝나기 전에 영속성 컨텍스트에 1차 캐쉬에 들어가 있는 데이터 상태를 변경 감지한다.

 

 

 

결과 화면

'프로그래밍 > JPA' 카테고리의 다른 글

JPA_테이블 생성  (0) 2023.06.06
JPA_JPA yml 파일 설정  (0) 2023.06.06
JPA_Pageable 페이징 처리  (0) 2023.05.13
JPA_JPA와 connection pool  (0) 2023.05.13