[Spring JPA #5] 엔티티 상태와 Cascade

| 엔티티 상태

  • JPA에서는 엔티티의 상태를 다음과 같이 나눈 후 사용자가 요청한 사항에 맞추어 관리하게 됩니다.

  • Transient : JPA가 엔티티를 나타내는 객체에 대한 정보를 모르는 상태

  • Persistent : JPA가 엔티티를 관리 중인 상태 (1차 캐시, Dirty Checking, Write Behind, ..)

    • Dirty Checking : 객체의 변경사항을 계속 감지
    • Write Behind : 객체의상태변화을 데이터베이스에 최대한 늦게, 필요한 시점에 반영한다는것이다.
  • Detached : JPA가 더이상 엔티티를 관리하지 않는 상태

  • Removed : JPA가 엔티티를 관리하는 상태에서 이 엔티티를 삭제하기로한 상태

  • save를 했다고 바로 DB에 쿼리를 날리는 것은 아니다.

  • Casade 옵션 : child에 있는 연관관계의 객체도 같이 persistent 상태가 되어 저장이 된다.

| CASCADE 옵션이 없을 경우

소스코드

package com.kyhslam;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Post {

    @Id @GeneratedValue
    private Long id;

    private String title;

    @OneToMany(mappedBy = "post")
    private Set<Comment> comments = new HashSet<>();

    public void addComment(Comment comment) {
        this.getComments().add(comment);
        comment.setPost(this);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Set<Comment> getComments() {
        return comments;
    }

    public void setComments(Set<Comment> comments) {
        this.comments = comments;
    }
}
package com.kyhslam;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
public class Reply {

    @Id @GeneratedValue
    private Long id;

    private String content;

    @ManyToOne
    private Post post;

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
  • 엔티티는 양방향 매핑이 되어 있는 상태이다.
  • Casecade옵션을 주지 않은 상태이기 때문에 아래의 ApplicationRunner를 실행시켜도 Post에 대한 정보만 DB에 저장이 되고 Reply는 반영되지 않는다.
package com.kyhslam;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.hibernate.Session;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;


@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        Post post = new Post();
        post.setTitle("Spring data Jpa");

        Reply reply = new Reply();
        reply.setContent("Seeing jpa");
        post.addReply(reply);

        Reply reply3 = new Reply();
        reply3.setContent("Seeing jpa22");
        post.addReply(reply3);

        Session session = entityManager.unwrap(Session.class);
        session.save(post);
    }
}

결과

| CASCADE 옵션을 적용했을 경우

  • Post 엔티티에 cascade = CascadeType.ALL 옵션을 적용하였다.
@Entity
public class Post {

    @Id @GeneratedValue
    private Long bno;

    private String title;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private Set<Reply> replys = new HashSet<>();

    public void addReply(Reply reply) {
        this.getReplys().add(reply);
        reply.setPost(this);
    }

    public Long getBno() {
        return bno;
    }

    public void setBno(Long bno) {
        this.bno = bno;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Set<Reply> getReplys() {
        return replys;
    }

    public void setReplys(Set<Reply> replys) {
        this.replys = replys;
    }
}

결과

SELECT * FROM post;

BNO|TITLE          |
---|---------------|
  1|Spring data Jpa|


SELECT * FROM reply;

ID|CONTENT     |POST_BNO|
--|------------|--------|
 2|Seeing jpa  |       1|
 3|Seeing jpa22|       1|

'📚 Spring > Spring JPA' 카테고리의 다른 글

[Spring JPA #7] Query  (0) 2020.07.15
[Spring JPA #6] Fetch  (0) 2020.07.15
[Spring JPA #4] 관계 맵핑  (0) 2020.06.28
[Spring JPA #3] Entity 매핑 및 Value 타입  (0) 2020.06.27
[Spring JPA #2] JPA 엔티티 매핑 용어 정리  (0) 2020.06.27

댓글

Designed by JB FACTORY