안녕하세요! 오늘은 Spring Framework
와 JPA
를 사용하여 의존 관계에 있는 테이블에 있는 데이터를 안전하게 삭제하는 방법에 대해 알아보겠습니다. 복잡한 데이터 모델에서는 하나의 엔티티가 다른 엔티티와 관계를 맺고 있을 때가 많습니다. 이러한 경우, 한 엔티티를 삭제할 때 관련 엔티티도 함께 삭제해야 할 필요가 있습니다. 오늘의 예제는 interior프로젝트에서 구현한 Album 엔티티와 이와 연관된 Image 엔티티들을 함께 삭제하는 상황을 살펴보겠습니다.
엔티티 관계 설정
먼저, Album과 Image 엔티티를 살펴보겠습니다. Album은 여러 Image 엔티티와 일대다 관계를 맺고 있습니다.
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Album {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Image> images;
private String caption;
@CreationTimestamp
private Timestamp createDate;
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String postImageUrl;
@JsonIgnoreProperties({"images"})
@ManyToOne
@JoinColumn(name = "album_id")
private Album album;
@CreationTimestamp
private Timestamp createDate;
}
여기서 중요한 점은 @OneToMany
어노테이션의 cascade = CascadeType.ALL
과 orphanRemoval = true
설정입니다. 이 설정은 Album 엔티티를 삭제할 때 연관된 모든 Image 엔티티들도 함께 삭제되도록 합니다.
삭제 로직 구현
@OneToMany
또는 @ManyToOne
어노테이션에 cascade = CascadeType.REMOVE
또는 cascade = CascadeType.ALL
옵션을 설정하면, 부모 엔티티를 삭제할 때 연관된 자식 엔티티들도 자동으로 삭제됩니다.
이 설정을 사용하면, Album 엔티티를 삭제하는 것만으로 자동으로 모든 연관된 Image 엔티티들이 삭제됩니다. 즉, 별도의 쿼리를 실행할 필요 없이 JPA가 관련된 자식 엔티티들의 삭제를 처리합니다.
이 방식을 사용하면 다음과 같은 간단한 삭제 메서드로 충분합니다:
@Transactional
public void 앨범삭제(int albumId) {
Album album = albumRepository.findById(albumId)
.orElseThrow(() -> new EntityNotFoundException("Album not found"));
albumRepository.delete(album);
}
만약 Album 엔티티가 아래와 같은 상황이라면 Image와 Album을 차례대로 삭제해주는 방법이 있습니다.
@OneToMany(mappedBy = "album")
private List<Image> images;
@Transactional
public void 앨범삭제(int albumId) {
// 앨범과 연관된 이미지를 먼저 삭제
imageRepository.deleteByAlbumId(albumId);
// 그 다음 앨범 삭제
albumRepository.deleteById(albumId);
}
이 메서드는 먼저 Image 테이블에서 해당 Album ID를 가진 모든 이미지를 삭제합니다. 그 후 Album 자체를 삭제합니다.
여기서 "deleteByAlbumId는 Spring Data JPA 문법으로 ImageRepository에 다음과 같이 선언해주어야 합니다.
void deleteByAlbumId(int albumId);
void 혹은 int를 사용해주시면 됩니다.
결론
JPA와 Spring Framework를 사용하면 데이터베이스에서 의존 관계에 있는 테이블의 데이터를 안전하고 효율적으로 관리할 수 있습니다. @Transactional
과 JPA의 캐스케이딩 옵션
을 활용하면 복잡한 데이터 관계도 쉽게 처리할 수 있습니다.
감사합니다.
'Backend > 🌿Spring' 카테고리의 다른 글
[Spring Boot] 사진 업로드 기능 구현하기 Back-end , 1편 (1) | 2024.01.23 |
---|---|
[JPA/Error] 무한 참조 문제 해결하기 @JsonIgnoreProperties 활용 (0) | 2024.01.21 |
[SpringBoot/Error] Required URI template variable 'id' for method parameter type int is not present 해결 (0) | 2024.01.19 |
[Spring] 좋은 객체 지향 설계의 5가지 원칙 (SOLID) (2) | 2023.10.11 |
[Spring Boot] application.yml 내용 secret으로 관리하기 (0) | 2023.09.02 |