[JPA] Entity에 정말 Setter를 쓰면 안될까?

HwangDo·2023년 7월 7일
1

JPA

목록 보기
2/7
post-thumbnail
post-custom-banner

Entity에 Setter 넣지 마세요!

JPA에 대해 어느정도 공부한 분들의 글을 보면, EntitySetter를 넣지 말라고 하는 내용이 많다.
습관성으로 @Getter, @Setter를 붙여두던 나에겐 대체 왜 쓰지 말라는건지 이유가 궁금해졌다.


@Setter를 지양해야 하는 이유

1. 의도가 불분명하다.

다음 코드를 살펴보자.

user.setEmail("hwangdo@exam.com");

이 짧은 한줄짜리 코드는 무엇을 위해 작성되었을까?
"사용자의 이메일 정보를 설정" 은 맞는말이긴 하다. 하지만 새로 생긴 User의 이메일을 설정해 주는 것인지, 기존 User의 이메일을 업데이트 해주는 것인지 이 코드만으로는 이해 할 수 없다.
이렇게 의도가 불분명해지는 메서드는 프로젝트 규모가 커질수록 의도치 않은 실수가 발생할 확률이 높아진다. 이는 객체의 일관성이 보장되지 않는다고 볼 수 있다.


@Setter의 대안

그렇다고 그냥 단순히 Setter를 빼버리면, 엔티티의 수정이 아예 불가능해진다. 이렇게 아예 Immutable하게 만드는 것은 일관성 부분에서 큰 이점이 있겠지만, 코드를 작성하는 개발자 입장에선 너무나도 불편하다.
따라서 다음과 같은 방법을 도입 할 수 있다.

1. 객체의 생성시에는, 생성자 사용

먼저, 처음 만드는 객체일 경우엔 생성자를 통해 값을 넣어주면 된다.

    @Builder
    public Question(String title, String context, String writer, String password) {
        this.title = title;
        this.context = context;
        this.writer = writer;
        this.password = password;
    }

Lombok 라이브러리를 사용하면, 이렇게 위에 @Builer annotation을 붙여 빌더 패턴으로 사용 할 수 있다.
빌더 패턴이란?
만약, 객체의 필드가 많아진다면 개발자는 생성자 파라미터의 순서를 외워서 작성하기 힘들어진다. IDE에서 힌트를 주기도 하지만, 수십개의 필드가 있다면 실수의 확률도 올라간다.

Question question = Question.builder()
                .title("제목")
                .context("내용내용")
                .writer("작성자")
                .password("pw")
                .build();

따라서 빌더 패턴을 도입하면, 이렇게 마치 메서드의 형태처럼 값을 넣어줄 수 있다. StringBuilder를 간략하게라도 써본 사람은 이해가 잘 될것이다.

2. 객체의 수정시에는, Setter가 아닌 메서드를 새로 만든다.

Setter의 문제는, 의도를 파악하기 힘들다는 것이였다. 따라서, 메서드 이름만으로 의도를 파악할수 있도록 구성한다.

public void updateUserEmail(String email){
	this.email = email;
}

위와 같이, 사용하는 사람 입장에서 정확한 의도를 파악할수 있도록 메서드 이름을 정의하는것이 좋다.

근데 꼭 Setter가 필요할때는?

Setter를 쓰는것은 지양해야 하는것이지, 금기사항이라고 볼수는 없을 것 같다.
관리만 잘 한다면, Setter를 써도 괜찮을 수 있다.
그러나 내가 더 나은 코드를 위해, Entity에 Setter를 도입하지 않는 방법에 대한 고민한 내용이 있다.
[SpringBoot] @ModelAttribute 사용시 바인딩이 안되는 문제
트러블 슈팅중 나온 방법이지만, DTO를 도입함으로서 문제를 해결했다.

profile
제가 배워가는 내용과, 실수한 부분을 정리합니다
post-custom-banner

0개의 댓글