Notice : File 테이블은 1:N 연관관계로 설정되어있음
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Table(name = "notices")
public class Notice extends TimeStamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long noticeId;
...
@OneToMany(mappedBy = "notice", cascade = CascadeType.ALL, orphanRemoval = true)
List<File> fileList = new ArrayList<>();
...
}
Java
복사
orphanRemoval = true 를 통해 공지가 삭제되면 파일의 연관관계가 null로 사라지므로 함께 삭제된다. 해당 옵션은 위험하기 때문에 잘 생각해서 적용해야한다. 특히 User에 잘못 연결하는 경우 user가 생성한 게시판, 게시글, 모두 사라질 수 있다.
테스트
18번 공지를 삭제했으며, 이는 2개이상의 파일이 연결되어 있었다.
공지가 삭제되었으며
연관되어있던 첨부파일도 모두 삭제되었다.
하지만 실제 파일이 저장된 디렉토리에는 파일이 남아있다.
이것을 삭제할지, 그대로 두어야할지는 프로젝트 성격에 따라 바뀔것 같다.
현재 프로젝트에서는 큰 의미가 없기 때문에 백업차원에서 두려고하지만, 원본 파일을 삭제해야되는 경우가 있을것 같다.
기본적으로 파일이 파일 시스템과 데이터베이스 간의 불일치를 나타내기때문에 실제 파일 삭제까지 구현해보고자한다.
19번 공지글을 삭제하면서 첨부파일 삭제를 확인
Service계층에서 공지 삭제에서 파일 삭제 관련 메소드를 추가한다.
@Service
@RequiredArgsConstructor
public class NoticeService {
private final NoticeRepository noticeRepository;
private final BoardService boardService;
private final FileService fileService;
private final FileRepository fileRepository;
...
// 공지글 삭제
@Transactional
public StatusResponseDto deleteNotice(Long noticeId) {
Notice deleteNotice = findNoticeById(noticeId);
// 연관된 파일 삭제
for (File file : deleteNotice.getFileList()) {
fileService.deleteFile(file.getFileUrl());
}
noticeRepository.delete(deleteNotice);
return new StatusResponseDto("공지글이 삭제되었습니다.", HttpStatus.OK.value());
}
...
}
Java
복사
FileService 계층에서 해당 메소드를 추가한다.
// 파일 삭제 로직
public boolean deleteFile(String fileUrl) {
File file = new File(fileUrl);
return file.delete();
}
Java
복사
File 엔티티에서 Url을 통한 삭제 메소드를 추가한다.
// 파일 경로를 통한 생성자
public File(String fileUrl) {
this.fileUrl = fileUrl;
}
// 파일 삭제 로직
public boolean delete() {
File file = new File(this.fileUrl);
return file.delete();
}
Java
복사
notice_id 가 19번인 공지는 1개의 첨부파일이 있다.
삭제 시도시 무한루프가 발생한다.
File 엔티티 내 delete() 메소드의 문제가 있다. File객체가 java.io로부터 생성되도록 직접 명시적으로 작성해준다.
// 파일 삭제 로직
public boolean delete() {
java.io.File file = new java.io.File(this.fileUrl);
return file.delete();
}
Java
복사
정상적으로 삭제되는 것을 확인 할 수 있다.
19번 공지가 삭제되었으며, 첨부파일 또한 삭제되었다.
실제 시스템 디렉토리 내의 파일도 삭제된 것을 확인 할 수 있다.