hades

[JPA] 생명주기 일치 시 참조 변경의 위험성 본문

🏃🏻‍♂️ 기본훈련/Java

[JPA] 생명주기 일치 시 참조 변경의 위험성

hades1 2024. 8. 19. 18:06

🚨 에러

A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance

 

🔍 분석

에러를 그대로 해석해보면, cascade="all-delete-orphan" 옵션이 있는 컬렉션이 더이상 엔티티 객체에 의해 참조되지 않는다고 한다.

 

문제가 발생하는 부분인 Post는 다음과 같다.

@Entity
@Getter
@Setter
public class Post {

    @Id
    @GeneratedValue
    @Column(name = "POST_ID")
    private Long id;

    private String comment;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UploadFile> imageFiles = new ArrayList<>();
	
    ...
    
    // 수정 메서드
	public void modifyPost(List<UploadFile> imageFiles, String comment) {
        if (!imageFiles.isEmpty()){
            this.getImageFiles().removeAll(getImageFiles());
            this.setImageFiles(imageFiles);
            for (UploadFile imageFile : imageFiles) {
                imageFile.setPost(this);
            }
        }

        this.setModifiedTime(LocalDateTime.now());
        this.setComment(comment);
    }
}

 

cascade와 orphanRemoval 설정은 imageFiles에 있고, Post애서 imageFiles에 대한 연관관계를 끊어버리면, 자동 삭제 시키기 위해서 사용했다. 글을 수정하는 과정에서 이미지를 변경할 때, 참조 자체를 갈아치웠기 때문에 문제가 발생한다.

 

👊 해결

// 수정 메서드
public void modifyPost(List<UploadFile> imageFiles, String comment) {
    if (!imageFiles.isEmpty()){
        this.getImageFiles().removeAll(getImageFiles());
        for (UploadFile imageFile : imageFiles) {
            this.getImageFiles().add(imageFile);
            imageFile.setPost(this);
        }
    }
    this.setModifiedTime(LocalDateTime.now());
    this.setComment(comment);
}

참조는 그대로 유지하고, 비운 리스트에 추가하는 방식으로 해결했더니 잘 동작한다.