본문 바로가기
Spring/Spring Study

[Spring] @Data는 왜 지양해야 하는 것일까?

by ♡˖GYURI˖♡ 2024. 7. 4.
728x90
팀 프로젝트를 진행하며 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