dirtychecking(변경 감지)
post를 수정하고 저장할 때, author 데이터도 자동으로 수정이 반영되게 만들어보자.
"수정" 작업을 통해 한 군데를 수정하고 저장했을 때, 그 한 쪽이 가지고 있는 다른 쪽이 연쇄되어 수정되는 것.
이 경우, authorRepository.save(author)를 해주지 않아도 JPA가 자동으로 변경사항을 반영해준다.
- JPA는 트랜잭션이 커밋될 때 영속성 컨텍스트 내의 엔티티를 스캔하여 변경된 엔티티 검색
- 변경된 엔티티가 감지되면, JPA는 save가 없어도 해당 변경 사항을 데이터베이스에 자동으로 반영
[ PostService.java ]
public void save(PostCreateReqDto postCreateReqDto){
Author author = authorRepository.findByEmail(postCreateReqDto.getEmail()).orElse(null);
Post post = Post.builder()
.title(postCreateReqDto.getTitle())
.contents(postCreateReqDto.getContents())
.author(author)
.build();
//더티체킹 테스트
author.updateAuthor("dirty checking test", "1234");
postRepository.save(post);
}
게시글을 수정하면, 수정하고 있는 author의 이름이 dirty checking test, 비밀번호 1234로 변경된다.
기존에 가입 이력이 있는 이메일인 yd@naver.com이 쓴 글을 수정한다.
yd@naver.com이 쓴 글을 수정하게 되면,
author 객체의 name은 dirty checking test로, password는 1234로 자동으로 변경된다.
더티체킹이 되지 않는다면
authorRepository.save(author); 코드를 통해 author의 변경사항도 DB에 수정해줘야 한다.
cascading
"삽입, 삭제" 작업을 수행했을 때, 수정한 쪽과 관련된 다른 쪽이 연쇄되어 수정되는 것
- Cascade를 사용하면, 부모 엔티티를 저장할 때 자동으로 연관된 자식 엔티티들도 함께 저장함으로서 코드를 간결하게 만들고, 엔티티 간의 관계를 명확하게 표현
- 더티체킹과 비교하면 더티체킹은 변경사항에 대해서만 반영하지만 cascade옵션을 통해서는 연관엔티티의 신규 사항 추가 가능
- Cascade 옵션은 일반적으로 부모 엔티티에 설정한다.
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch=FetchType.LAZY) //Post 객체에 있는 변수명을 적어 매핑관계 표현
private List<Post> posts; // posts 리스트에 post가 생성될 때마다 Post 테이블 가서 생성해줌
//AuthorRepository.save만 해줘도 자동으로 PostRepository.save까지 해줌
[ AuthorService.java ]
public void save(AuthorSaveReqDto authorSaveReqDto) {
Role role = null;
if(authorSaveReqDto.getRole() == null || authorSaveReqDto.getRole().equals("user")){
role = Role.USER;
}else{
role = Role.ADMIN;
}
//일반 생성자 방식
//Author author = new Author(authorSaveReqDto.getName(), authorSaveReqDto.getEmail(), authorSaveReqDto.getPassword(), role);
//빌더패턴
// .build() : 최종적으로 완성시키는 단계
Author author = Author.builder()
.email(authorSaveReqDto.getEmail())
.name(authorSaveReqDto.getName())
.password(authorSaveReqDto.getPassword())
.build();
// //cascade.persist 테스트
//부모 테이블을 통해 자식 테이블에 객체를 동시에 생성
List<Post> posts = new ArrayList<>();
Post post = new Post.builder()
.title("안녕하세요. " + author.getName() + "입니다.")
.contents("반갑습니다. cascade 테스트 중입니다..")
.author(author)
.build();
posts.add(post);
author.setPosts(posts); // setter를 사용하지 않기 위해 Post 생성자에 this.author.getPosts(this);
//위 post 생성 주석을 풀 경우, author만 save해줘도 post까지 save됨 => cascade ⭐
authorRepository.save(author);
}
author객체에 posts객체를 set하여 author객체를 save할 경우 cascade옵션이 설정돼 있으면 post객체에도 save된다.
'Back-End 공부 > Spring' 카테고리의 다른 글
[스프링] 스케줄링 cron 사용하기 (1) | 2024.02.03 |
---|---|
[스프링] 지연로딩, 즉시로딩, N+1문제 제대로 이해하기 (0) | 2024.01.26 |
[스프링] Paging 기능 구현 (0) | 2024.01.26 |
Spring에서 발생하는 대표적인 순환참조 문제 해결하기 (0) | 2024.01.24 |
생성자 객체 생성 방식의 단점을 극복한 builder 패턴 (1) | 2024.01.23 |