티스토리 뷰

JPA

[JPA] JPA Data Delete

크리드보이

 JPA 연관관계가 존재할 때 Entity 삭제하기

JPA 프로젝트를 진행하던 중, 회원 탈퇴를 진행할 때 User와 그에 연관된 Entity에서 @ManyToOne 관계에서 영속성 관리에서 문제가 발생되었다.

그냥 User Data를 delete하려고하면 다음과 같은 Error가 발생한다.

Cannot delete or update a parent row: a foreign key constraint fail

참조된 객체를 지워주지 않았기 때문에 발생하였다.



OneToMany Cascade

처음에는 @ManyToOne 어노테이션에 cascade option을 부여해서 영속성을 부여 해 보았다.
그러나 User를 Delete할 때 위와 같은 오류가 계속해서 발생했다.

결론적으로 찾은 이유는 내가 단방향으로 child에게 parent만을 Mapping했기 때문이다.
parent는 child를 매핑하지 않았기 때문에 계단식으로 데이터가 삭제되는데 실패했다.

그래서 둘을 양방향으로 연결 해 주는 것을 우선적으로 해야했다.

 

@OneToMany 어노테이션으로 parent Entity에 List나 Set 형식으로 child를 Mapping 해 주었다.

  • 이 때 @OneToMany의 mappedBy 옵션에는 실제 내가 child 셋팅한 변수명과 똑같이 설정 해주어야한다.

나는 이 부분 때문에 계속

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property

에러가 발생했었는데 변수명을 일치시키지 않아서 생긴 문제였다.



Entity 구현


@Entity
@Getter
@Setter
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    ...


    @OneToMany(mappedBy = "userId", cascade = {CascadeType.ALL}, orphanRemoval=true)
    private List<UserConference> userConferences;

    ....
}
@Entity
@Getter
@Setter
public class UserConference {

  ...

  @ManyToOne
  @JoinColumn(name="User_ID", referencedColumnName = "ID")
  private User userId;



}

위와 같이 mappedBy는 child의 변수명과 일치시켜야한다.

모든 관계에 대해서 양방향 설정을 마치고,
cascade 옵션을 ALL로 주었다.

위 과정을 마친 후 유저 삭제가 계단식으로 잘 처리 되는 것을 확인하였다.



+ Cascade Type

  • CascadeType.PERSIST
    엔티티를 영속화 할 때이 필드에 보유 된 엔티티도 유지합니다. EntityManager가 flush 중에 새로운 엔티티를 참조하는 필드를 찾고이 필드가 CascadeType.PERSIST를 사용하지 않으면 오류이므로이 Cascade 규칙의 자유로운 적용을 제안합니다.
  • CascadeType.MERGE
    엔티티 상태를 병합 할 때, 이 필드에 보유 된 엔티티도 병합하십시오.
  • CascadeType.REFRESH
    엔티티를 새로 고칠 때, 이 필드에 보유 된 엔티티도 새로 고칩니다.
  • CascadeType.REMOVE
    엔티티를 삭제할 때, 이 필드에 보유 된 엔티티도 삭제하십시오.
  • CascadeType.DETACH
    부모 엔티티가 detach()를 수행하게 되면, 연관된 엔티티도 detach() 상태가 되어 변경사항이 반영되지 않는다.
  • CascadeType.ALL
    모든 Cascade 적용
댓글
Total
최근에 올라온 글