[Spring JPA #6] JPA Cascade

2021. 3. 25. 03:11 Spring Data/Spring Data JPA

| 엔티티 Cascade 

 

엔티티 Cascade는 엔티티의 상태 변화를 전파시키는 옵션입니다. 단방향 혹은 양방향으로 매핑되어 있는 엔티티에 대해 어느 한쪽 엔티티의 상태(생성 혹은 삭제)가 변경되었을 시 그에 따른 변화를 바인딩된 엔티티들에게 전파하는 것을 의미합니다.

 

| Cascade 옵션을 주지 않았을 경우

 

프로젝트 구조

├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── tutorial
│   │   │           └── springbootjpa
│   │   │               ├── Comment.java
│   │   │               ├── JpaRunner.java
│   │   │               ├── Post.java
│   │   │               ├── SpringBootJpaApplication.java
│   │   └── resources
│   │       ├── application.properties
│   │       ├── static
│   │       └── templates

 

의존성 관리

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

 

소스 코드

@SpringBootApplication
public class SpringBootJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootJpaApplication.class, args);
    }

}
@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.comments.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;
    }
}
@Entity
public class Comment {

    @Id
    @GeneratedValue
    private Long id;

    private String comment;

    @ManyToOne
    private Post post;

    public Long getId() {
        return id;
    }

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

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }
}
  • 게시판에 대한 정보를 나타내는 엔티티인 Post와 게시판 댓글을 나타내는 Comment 엔티티가 있습니다. 이 두 엔티티는 양방향 매핑이 되어 있는 상태입니다.
  • 현재 Casecade 옵션을 주지 않은 상태이므로 아래의 ApplicationRunner 를 실행시켜도 Post에 대한 정보만 DB에 반영될 뿐 Comment 정보에 대한 것은 반영되지 않습니다.
@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 Title");

        Comment comment = new Comment();
        comment.setComment("Great Spring Data");
        post.addComment(comment);

        Comment comment1 = new Comment();
        comment1.setComment("Yes it is");
        post.addComment(comment1);

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

 

 

결과 화면

springboot=# select * from post;
id |       title
----+-------------------
1 | Spring Data Title
(1 row)

springboot=# select * from study;
id | name | owner_id
----+------+----------
(0 rows)

 

| Cascade 옵션을 적용했을 경우

 

다음과 같이 Cascade 옵션을 적용했을 경우에는 위에서 영속화되지 않았던 Comment 엔티티가 영속화되는 것을 확인할 수 있습니다.

 

소스 코드

@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.comments.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;
    }
}

 

결과 화면

springboot=# select * from post;
id |       title
----+-------------------
1 | Spring Data Title
(1 row)

springboot=# select * from comment;
id |      comment      | post_id
----+-------------------+---------
2 | Yes it is         |       1
3 | Great Spring Data |       1
(2 rows)

 

https://www.inflearn.com/course/스프링-데이터-jpa



출처: https://engkimbs.tistory.com/817?category=772527 [새로비]