@ManyToOne 필드에@ToString.Exclude를 붙이는 이유는 양방향 관계에서 발생할 수 있는 순환 참조(Circular Reference) 문제를 방지하기 위해서입니다.
1. 문제의 원인: 순환 참조
JPA의 양방향 매핑에서 부모-자식 관계를 가지는 두 엔티티는 서로를 참조하게 됩니다.
예를 들어, Parent는 Child 목록을 가지고 있고, Child는 다시 Parent를 참조하는 구조가 있을 수 있습니다.
이 상태에서 toString()을 호출하면, 한 엔티티의 toString()이 다른 엔티티의 toString()을 호출하는 무한 루프가 발생할 수 있습니다.
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> children;
}
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
private Parent parent;
}
위 엔티티에서 Parent와 Child가 서로를 참조합니다.
만약 toString() 메서드가 자동 생성되어 있으면:
1. Parent의 toString()은 children 리스트를 출력하려고 Child 객체들의 toString()을 호출.
2. Child의 toString()은 다시 parent 객체의 toString()을 호출.
3. 이 과정이 계속 반복되면서 StackOverflowError가 발생.
2. 해결 방법: @ToString.Exclude
Lombok의 @ToString.Exclude를 사용하여 특정 필드를 toString() 결과에서 제외하면, 순환 참조 문제를 방지할 수 있습니다.
수정된 예제
@Entity
@ToString
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> children;
}
@Entity
@ToString
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@ToString.Exclude
private Parent parent; // 순환 참조 방지
}
이제 Child의 toString()에서 parent는 제외되므로 Parent와 Child 간 순환 참조가 발생하지 않습니다.
3. 사용 시 주의할 점
1. 양방향 관계의 필드에 주로 사용: 순환 참조 문제가 발생할 가능성이 있는 필드에만 적용.
2. 비즈니스 로직에 영향 없음: @ToString.Exclude는 단지 toString() 출력에 영향을 주며, 엔티티의 데이터베이스 매핑이나 로직에는 영향을 미치지 않습니다.
만약 Lombok을 사용하지 않는다면, 수동으로 toString()을 작성하여 문제를 방지할 수 있습니다.
4. 결론
1. @ToString.Exclude는 순환 참조 문제를 간단하게 방지하는 데 유용합니다.
2. 특히, @ManyToOne과 같은 양방향 관계에서 사용하는 것이 일반적입니다.
3. 이런 조치를 통해 StackOverflowError 같은 예외 상황을 사전에 예방할 수 있습니다
'Spring > Spring JPA' 카테고리의 다른 글
[JPA] spring.jpa.properties.hibernate.dialect (0) | 2024.12.04 |
---|---|
[JPA] 영속성 컨텍스트(Persistence Context) (0) | 2024.12.03 |
[JPA] JPA에서 관계를 매핑할 때 사용하는 어노테이션 (0) | 2024.11.27 |
[JPA]@ToString.Exclude (0) | 2024.11.25 |
[JPA] @OneToOne (0) | 2024.11.25 |