상황
사용자가 특정 House에 대해 찜을 해제하려고 할 때, Pin 엔티티가 삭제되어야 하는데, 의도치 않게 User와 House 엔티티까지 삭제되는 문제가 발생했습니다.
원인
@ManyToOne 관계에 설정된 cascade = CascadeType.ALL은 부모 엔티티에서 발생하는 모든 영속성(Persistence) 작업(예: PERSIST, MERGE, REMOVE 등)을 연관된 자식 엔티티에도 전파하도록 지정한다.
house와 user는 @ManyToOne 관계에서 Pin과 연관되어 있으며, CascadeType.ALL로 설정되어 있습니다. 따라서 Pin 삭제 시 JPA는 이 연관된 엔티티들도 함께 삭제하도록 동작한다.
pinRepository.deleteByUserAndHouse(user, house); // 여기서 삭제 됨
@Entity
@Table(name="pin")
@Data
public class Pin {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "house_id")
private House house;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;
}
CascadeType은 JPA에서 연관 관계를 맺고 있는 엔티티들 간에 특정 작업을 어떻게 전파할지 설정하는 옵션이다. 주로 부모 엔티티에서 수행된 작업이 자식 엔티티에 전파되도록 하기 위해 사용된다.
CascadeType 종류
- PERSIST: 부모 엔티티가 저장될 때, 연관된 자식 엔티티도 저장된다. 예를 들어, CascadeType.PERSIST를 설정하면 부모 엔티티를 저장할 때 자식 엔티티도 자동으로 저장된다.
- MERGE: 부모 엔티티가 병합될 때, 연관된 자식 엔티티도 병합된다. 부모 엔티티가 병합될 때 자식 엔티티의 상태도 반영된다.
- REMOVE: 부모 엔티티가 삭제될 때, 연관된 자식 엔티티도 삭제된다. 부모 엔티티를 삭제할 때 연관된 자식 엔티티도 함께 삭제된다.
- REFRESH: 부모 엔티티가 리프레시될 때, 연관된 자식 엔티티도 리프레시된다. 부모 엔티티의 상태가 DB와 일치하도록 갱신될 때 자식 엔티티도 갱신된다.
- DETACH: 부모 엔티티가 분리될 때, 연관된 자식 엔티티도 분리된다. 부모 엔티티가 영속성 컨텍스트에서 분리되면 자식 엔티티도 함께 분리된다.
- ALL: 모든 작업이 자식 엔티티에 전파된다. 즉, PERSIST, MERGE, REMOVE, REFRESH, DETACH 모두 자식 엔티티에 전파된다.
해결
CascadeType.PERSIST 로 설정하여 저장될때만 연관되고, 삭제될땐 pin말고 다른 엔티티도 전파되지 않도록 설정합니다.
@Entity
@Table(name="pin")
@Data
public class Pin {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "house_id")
private House house;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "user_id")
private User user;
}
반응형
'Server > 🌱 Spring Boot (java)' 카테고리의 다른 글
[Spring Boot] Record 객체를 이용하여 DTO 작성 (0) | 2025.01.25 |
---|---|
[Spring boot jpa] 연관된 엔티티 불러올때 LazyInitializationException 발생하는 문제 해결 (0) | 2025.01.25 |
[Spring boot] SQL 예약어와 테이블 이름 충돌 문제 해결 (0) | 2025.01.25 |
[Spring boot] DataJpaTest를 이용한 Repository 테스트와 여러 문제 해결 (0) | 2025.01.25 |
[Spring boot] @Scheduled 어노테이션을 사용한 스케줄링이 작동하지 않는 문제 해결 (0) | 2025.01.25 |
댓글