팀 프로젝트를 진행하며 Controller, Service 등에 공통적으로 사용할 어노테이션 목록을 정하면서 또 토의가 열렸다. @Data를 사용하는 쪽이 편하다는 의견과 @Data를 지양하자는 의견이 나왔기 때문이다. 그래서 찾아보는 '@Data를 지양해야 하는 이유'!
@Data
@ToString, @Getter, @Setter, @EqualsAndHashCode, @RequiredArgsConstructor을 한 번에 사용하는 강력한 어노테이션
- @ToString : toString 메소드 자동생성
- @Getter : 모든 필드의 getter 메소드 자동생성
- @Setter : 모든 필드의 setter 메소드 자동생성
- @EqualsAndHashCode : equals, hashCode 메소드 자동생성
- @RequiredArgsConstructor : final이나 @NonNull인 필드 값만 파라미터로 받는 생성자 자동생
@Data를 지양해야 하는 이유
1. 무분별한 Setter 남용
- (팀원들끼리 이야기할 때 가장 먼저 나왔던 이유)
- Setter는 객체를 언제든지 변경할 수 있는 상태로 만들기에 객체의 안정성을 보장받기 어렵다.
2. ToString으로 인한 양방향 연관관계 시 순환 참조 문제
@Entity
@Table(name = "member")
@Data
public class Member {
....
@OneToMany
@JoinColumn(name = "coupon_id")
private List<Coupon> coupons = new ArrayList<>();
}
@Entity
@Table(name = "coupon")
@Data
public class Coupon {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne
private Member member;
public Coupon(Member member) {
this.member = member;
}
}
위와 같이 Member 객체와 Coupon 객체가 양방향 연관관계를 가질 경우 ToString을 호출하면 무한 순환 참조가 발생한다. JPA를 사용하다 보면 객체를 Json으로 직렬화하는 과정에서 발생하는 문제와 동일한 이유이다.
→ 이 부분이 무슨 말인지 감이 오지 않아 조금 더 찾아보았다.
Member 객체와 Coupon 객체가 양방향 연관관계를 가질 경우, Member의 toString 메소드가 호출되면 Coupon의 toString 메소드가 호출된다. 그리고 Coupon의 toString 메소드가 호출되면 다시 Member의 toString 메소드가 호출된다. 이 과정이 계속 반복되면서 스택 오버플로우가 발생할 수 있다는 것이다.
쉬운 해결 방법은 ToString 항목에서 coupons를 제외시키는 것이다.
@ToString(exclude = "coupons")
public class Member {...}
혹은 불필요한 @ToString을 사용하지 않는 것도 방법일 수 있을 것 같다.
3. @RequiredArgsConstructor 어노테이션으로 인한 문제
- 예를 들어 두 개의 타입 인스턴스 멤버를 선언한 상황에서 개발자가 선언된 인스턴스 멤버의 순서를 바꾸면, 개발자도 인식하지 못하는 사이에 lombok이 생성자의 파라미터 순서를 필드 선언 순서에 따라 변형하게 된다.
- 이 때, IDE가 제공해주는 리팩토링은 전혀 동작하지 않고, 두 필드가 동일한 타입이기 때문에 기존 소스에서도 오류가 발생하지 않아 아무런 문제 없이 동작하는 것으로 보이지만, 실제로는 입력된 값이 바뀌어 들어가는 상황이 발생한다.
@Setter의 남용 때문이라는 이유 한 가지만 알고 있었는데, 생각보다 신경써야 할 점이 많았다.차라리 @Data 말고 필요한 어노테이션만 하나씩 붙여 사용하는게 나을 것 같다는 생각이 들었다.
@Data 지양이유
@ToString, @Getter, @Setter, @EqualsAndHashCode, @RequiredArgsConstructor을 한번에 사용하는 강력한 어노테이션Setter는 그 의도가 분명하지 않고 객체를 언제든지 변경할 수 있는 상태가 되어서 객체의 안전성이
velog.io
[Spring/스프링부트] @Data 사용을 지양하는 이유 (= 단점)
[오늘의 궁금증] @Data 는 여러 어노테이션을 한 번에 쓸 수 있는 유용한 어노테이션이지만 한 편으로는 @Data 사용을 지양하기도 한다 그 이유가 뭘까? @Data 어노테이션이란? @ToString, @Getter, @Setter, @
ddururiiiiiii.tistory.com
'Spring > Spring Study' 카테고리의 다른 글
[Spring] fromEntity, toEntity, ofEntity? - DTO와 Entity 변환 (0) | 2024.07.04 |
---|---|
[Spring] 연관 매핑을 지양하라? (0) | 2024.07.04 |
[Spring] HTTP 메소드 : PUT과 PATCH의 차이 (0) | 2024.07.04 |
[JPA] 외래키 설정 (1) | 2024.04.19 |
[JPA] hibernate의 ddl-auto 속성의 종류 및 주의 (0) | 2024.04.19 |