Spring Boot JPA에서 Cascade는 엔티티 간의 연관 관계에서, 하나의 엔티티에 대한 작업(예: 저장, 삭제 등)이 연관된 다른 엔티티에도 전이(Cascade)되도록 설정하는 기능입니다. 이를 통해 관계된 엔티티들을 자동으로 관리할 수 있습니다.
예를 들어, 두 엔티티 User
와 Profile
이 @OneToOne
관계를 갖는다고 가정해봅시다. 만약 User
를 저장하면서 동시에 Profile
도 저장하려면 일반적으로 다음과 같은 코드가 필요합니다.
Profile profile = new Profile();
profile.setBio("Developer");
profileRepository.save(profile);
User user = new User();
user.setName("John");
user.setProfile(profile);
userRepository.save(user);
위 코드는 효율적이지 않습니다. 이를 개선하기 위해Cascade를 설정하면 User
엔티티를 저장하거나 삭제할 때 Profile
엔티티도 자동으로 저장되거나 삭제됩니다.
cascade
는 JPA의 @OneToOne
, @OneToMany
, @ManyToOne
, @ManyToMany
관계에서 사용됩니다. CascadeType
은 다음과 같은 여러 옵션을 제공합니다.
@OneToOne(cascade = CascadeType.ALL)
private Profile profile;
@OneToOne(cascade = CascadeType.PERSIST)
private Profile profile;
@OneToOne(cascade = CascadeType.MERGE)
private Profile profile;
@OneToOne(cascade = CascadeType.REMOVE)
private Profile profile;
@OneToOne(cascade = CascadeType.REFRESH)
private Profile profile;
@OneToOne(cascade = CascadeType.DETACH)
private Profile profile;
CascadeType.PERSIST
를 사용하면 부모 엔티티를 저장할 때 연관된 엔티티도 자동으로 저장됩니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
private Profile profile;
// Getters and setters
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
// Getters and setters
}
// 실행 코드
Profile profile = new Profile();
profile.setBio("Developer");
User user = new User();
user.setName("John");
user.setProfile(profile);
userRepository.save(user); // User와 Profile이 모두 저장됨
CascadeType.REMOVE
를 사용하면 부모 엔티티가 삭제될 때 연관된 자식 엔티티도 자동으로 삭제됩니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = CascadeType.REMOVE)
private Profile profile;
// Getters and setters
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
// Getters and setters
}
// 실행 코드
User user = userRepository.findById(1L).orElseThrow();
userRepository.delete(user); // User와 연관된 Profile도 삭제됨
Cascade 옵션은 여러 개를 조합하여 사용할 수도 있습니다.
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Profile profile;
CascadeType.ALL
은 모든 Cascade 작업을 수행하므로, 예상치 못한 삭제나 병합 등이 발생할 수 있습니다.mappedBy
와 cascade
설정을 명확히 해야 순환 참조 문제가 발생하지 않습니다.