[JPA] cascade, orphan 객체

박연주·2022년 8월 16일
0

JPA

목록 보기
3/8

Cascade

Cascade 옵션이란?

  • 엔티티의 상태 변화를 전파시키는 옵션이다.

  • OneToMany와 ManyToOne로 양방향 관계를 맺는 엔티티의 상태 변화를 전이시킬 때 사용한다.

  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속상태로 만듦



엔티티의 상태


Transient : JPA가 엔티티를 모르는 상태, 즉 최초의 객체들이 생성된 단계

Persistent : JPA가 관리중인 상태, DB에 들어간 것을 의미하지는 않는다. 즉 save() 메소드를 사용했다고 해서 바로 DB에 insert 되는 것은 아니며 이 상태를 Persistent라고 부른다.( 1차 캐시, Dirty Checking, Write Behind 등)

Detached : JPA가 더이상 관리하지 않는 상태.

Removed : JPA가 관리하긴 하지만 삭제하기로 한 상태.

예시

@Entity
class Post (
    @Id @GeneratedValue
    val id:Long?,
    val title:String
){
    @OneToMany(mappedBy = "post",cascade = [CascadeType.ALL])
    val comments:MutableSet<Comment> = HashSet()

    fun addComment(comment:Comment){
        this.comments.add(comment)
        comment.post = this
    }
}


@Component
class JpaRunner: ApplicationRunner{

    @PersistenceContext
    lateinit var entityManager: EntityManager;

    // @Transactional이 적용된 메소드에는 트랜잭션이 적용된다. JPA를 사용할 땐 Transaction 애노테이션을 달아주도록 하자.
    @Transactional
    override fun run(args: ApplicationArguments?) {
        val post = Post(null,"Spring Data JPA 언제 보냐")

        val comment = Comment(null,"빨리 보고 싶어요",post)
        post.addComment(comment)

        val comment2 = Comment(null,"곧 보여드릴게요",post)
        post.addComment(comment2)

        // Session 클래스는 하이버네이트이다. 즉, JPA를 구현하는 하이버네이트 클래스를 가져와서 하이버네이트의 API를 사용할 수 있다.
        val session = entityManager.unwrap(Session::class.java)
        session.save(post)
        val getPost = session.get(Post::class.java,1L)
        session.delete(getPost)
    }

테스트하면 Comment 테이블에서 삭제되는 Post 레코드의 PK를 FK로 갖고 있는 모든 레코드들이 삭제되는 것을 확인할 수 있다.





고아객체 (orphanRemoval = true)

  • 고아 객체 제거 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동 삭제
  • 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
  • 특정 엔티티가 개인 소유할 때 사용 (참조하는 곳이 하나일 때)
  • @OneToMany, @OneToOne만 가능
  • CascadeType.REMOVE 처럼 부모를 제거할 때 자식도 함께 제거됨

orphanRemoval = true


Parent parent = em.find(Parent.class, id);
parent.getChildren().remove(0);
// 자식 엔티티를 컬렉션에서 제거

DELETE FROM CHILD WHERE ID=?





Reference

cascade
ORM 표준 JPA 정리 노션

profile
하루에 한 개념씩

0개의 댓글