Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- OAuth2
- 다익스트라
- AuthenticationPrincipal
- 브루트포스
- 백기선
- Application Runner
- webjar
- EnableAutoConfiguration
- 백트래킹
- JsonSerializer
- rest api
- Application Event
- HATEOAS
- 스프링 부트
- Application Argument
- 리소스 서버
- 스프링부트
- 알고리즘
- 외부설정
- 리소스핸들러
- Spring Security
- 백준
- HttpMessageConverters
- cors
- @ConfigurationProperties
- application.properties
- WebApplication Type
- 정적 리소스
- @Profile
- JPA
Archives
- Today
- Total
아카이브
[스프링 데이터 JPA] JPA 프로그래밍 5. Cascade 본문
Cascade
엔티티의 상태변화를 전파시키는 옵션
Transient: JPA가 모르는 상태
- 데이터베이스에 들어갈지 안 들어갈지도 전혀 모르는 상태
- new Object()
- save()를 호출하기 전
Persistent: JPA가 관리중인 상태
- 1차 캐시: Persistent Context(EntityManager, Session)에 인스턴스를 넣은 것
- 아직 저장이 되지 않은 상태에서 다시 인스턴스를 달라고 하면 이미 객체가 있으므로 데이터베이스에 가지 않고 캐시 하고 있는 것을 줌
- save()를 호출한다고 바로 Insert 쿼리가 실행되는 것은 아니다.
- save()를 호출하면 PersistentContext에 Instance를 넣어서 1차 캐싱한다.
- Dirty Checking: 이 객체의 변경사항을 계속 감지
- Write Behind: 객체의 상태의 변화를 데이터베이스에 최대한 늦게 가장 필요한 시점에 적용을 함
- 원래 가지고 있던 객체의 값과 동일한경우 변경사항을 적용하지 않음
- 변경사항을 계속 감지하다가 처음이랑 똑같으면 update 하지 않는다.
Detached: JPA가 더이상 관리하지 않는 상태
- Transaction이 끝났을 때 DB에 실제로 저장되고 Session이 종료된 상태
Removed: JPA가 관리하긴 하지만 삭제하기로 한 상태
- delete() 호출
AccountStudyRunner 클래스에서 1차 캐시와 Write Behind 테스트
@Component
@Transactional
public class JpaRunner implements ApplicationRunner {
@PersistenceContext
EntityManager entityManager;
@Override
public void run(ApplicationArguments args) throws Exception {
/*
* Transient 상태 : JPA가 아무것도 모르는 상태
* */
Study study = new Study();
study.setName("Spring Data JPA");
Account account = new Account();
account.setUsername("WON");
account.setPassword("hibernate");
account.addStudy(study); /* 양방향 관계 설정하기 */
Session session = entityManager.unwrap(Session.class); /* 하이버네이트의 가장 핵심적인 API는 Session이다.*/
session.save(post);
/*
* Persistent 상태 : JPA가 관리중인 상 (1차 캐시)
* save를 호출한다고 해서 바로 INSERT 쿼리가 발생하는 것은 아니다.
* save를 호출하면 1차 캐시 : PersistenceContext에 이 instance를 넣어서 캐싱한다.
* */
session.save(account);
session.save(study);
Account load = session.load(Account.class, account.getId());
load.setUsername("WON 1");
load.setUsername("WON 2");
load.setUsername("WON");
/*
* 이렇게 했는데도 update 쿼리가 실행되지 않는다.
* 1. Dirty Checking (이 객체의 변경사항을 감시한다)
* 2. Write Behind (객체의 변경사항을 최대한 늦은 시점에 반영한다.)
*
* 계속 감시하다 보니까 변경사항이 처음이랑 똑같다.(WON -> WON 1 -> WON 2 -> WON)
* update 하지 않겠다.
* */
System.out.println("========== 현재 상태에서는 캐싱된 값을 보여주므로 이게 끝나고 INSERT가 동작한다. ==========");
System.out.println("========== 실제 INSERT는 트랜잭션이 끝날때 발생한다. ==========");
System.out.println(load.toString());
}
}
Post, Comment Cascade 테스트하기
Parent인 Post 클래스 생성
@Entity
public class Post {
@Id @GeneratedValue
private Long id;
private String title;
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL) // 전파하라
private Set<Comment> comments = new HashSet<>();
public void addComment(Comment comment) {
this.getComments().add(comment);
comment.setPost(this);
}
}
Child인 Comment 클래스 생성
@Entity
public class Comment {
@Id @GeneratedValue
private Long id;
private String comment;
@ManyToOne
private Post post;
}
Post-Comment CascadeType.ALL 일 때 save() 테스트
@Override
public void run(ApplicationArguments args) throws Exception {
//Post-Comment CASCADE 예제
Post post = new Post();
post.setTitle("Spring DATA JPA 포스트 타이틀");
List<Comment> comments = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Comment comment = new Comment();
comment.setComment("Comment " + i);
post.addComment(comment);
}
Session session = entityManager.unwrap(Session.class); /* 하이버네이트의 가장 핵심적인 API는 Session이다.*/
session.save(post);
// CascadeType.ALL 이므로 post를 save()할때, comment들도 함께 전파되어 들어간다.
}
보통 cascade=CascadeType.ALL 로 모두 전파하도록 설정한다.
'Spring > 스프링 데이터 JPA' 카테고리의 다른 글
[스프링 데이터 JPA] JPA 프로그래밍 7: Query (0) | 2021.01.10 |
---|---|
[스프링 데이터 JPA] JPA 프로그래밍 6: Fetch (0) | 2021.01.10 |
[스프링 데이터 JPA] JPA 프로그래밍 4. 1대다(관계) 맵핑 (0) | 2021.01.10 |
[스프링 데이터 JPA] JPA 프로그래밍 3. Value 타입 맵핑 (0) | 2021.01.10 |
[스프링 데이터 JPA] JPA 프로그래밍 2. 엔티티 타입 맵핑 (0) | 2021.01.10 |