본문 바로가기
Spring/Spring

[JPA] Entity에 setter 사용을 지양하는 이유

by 작은돼지 2023. 7. 15.

엔티티에 setter가 있다고해서 무조건 나쁘다는 뜻은 아니다.

엔티티 설계에 관한 다수의 의견을 종합했을 때 setter를 쓰지 않는 것을 권장하고 있다.

 

엔티티에 setter가 있다면

양방향 바인딩의 경우 setter가 있다면 훨씬 더 간단하게 구현할 수 있고

엔티티 필드의 값을 직접 변경할 수 있기 때문에

Dirty checking을 곧바로 사용할 수 있다는 장점(?)이 있다.

 

하지만 setter를 사용해 값을 어디선가 직접 변경할 수 있다면

그만큼 일관성이 깨질 수 있다는 위험이 있다.

일관성이 깨진다면 객체의 상태 추적을 하기 어려워지고 파급 효과를 잡기 어려워진다.

아래는 setter 사용을 지양해야하는 이유이다.

 

1. 불명확한 사용 의도

user.setName("짱구");
user.setAge(20);

여기서 set 메서드는 새로운 값을 set하는지, 기존의 값을 update하는지 알 수 없다.

사용 의도가 명확하지 않다.

 

2. 일관성 유지

public setter인 경우 외부에서 객체 내부 상태를 변경할 수 있기 때문에 일관성이 깨질 수 있다.

그러려면 각 setter마다 유효성 검사 코드가 추가되어야 한다.


그렇다면 setter 없이 엔티티의 값을 어떻게 담을까?

1. 별도의 업데이트 메서드를 추가하는 방법

private String name;
private int age;

public void updateAge(int age) {
	this.age = age;
}

setter 메서드를 제거하고 getter만 남은 상태이다.

 

이렇게 updateAge 메서드를 추가하면

앞서 말한 불명확한 사용 의도에 따른 문제점은

update 메서드를 사용함으로써 의도를 파악할 수 있고

일관성 유지 관련해선 age 필드는 값을 변경해도 되기 때문에 update 메서드가 존재하는 것이다.

 

여기서는 하나만 업데이트했지만

변경할 값들을 여러개 담아 다수의 필드를 업데이트할 수도 있다.

 

2. Builder 사용(생성자 사용)

@Builder
public User(String name, int age) {
	this.name = name;
	this.age = age;
}

롬복 어노테이션을 사용했다.

@Builder 어노테이션은 클래스 단위보다 생성자 위에 사용을 권장한다.

만약 클래스 위에 @Builder와 @AllArgsConstructor을 같이 사용하게되면

객체 생성 시 의도하지 않은 값을 설정할 수 있기 때문이다.

 

return User.builder()
	.name(userDto.getAge())
	.age(userDto.getAge())
	.nickname(userDto.getNickname())
	.gender(userDto.getGender())
	.hobby(userDto.getHobby())
	.build();

그리고 Builder가 주는 장점은

저 값들을 생성자 파라미터에 가득 담아서 보내는 것보다

어떤 값에 무엇이 들어가는지 알 수 있어 가독성이 좋다는 장점이 있다.

 

이렇게 Builder를 사용하면 객체의 생성 시점에 의도한 값을 대입해줄 수 있어

setter를 사용하지 않아도 된다.


그렇다면 어떤 방법이 최선인가?

엔티티 설계에 관해선 명확한 규정이 없다.

엔티티의 책임: 데이터베이스에 대응되는 Java 클래스

 

프로젝트 협의나 개인 재량에 따라 선택해야 한다.

 

1. (가장 넓은)엔티티에 비즈니스 로직을 허용한다.

- 엔티티가 뚱뚱해지며 그만큼 책임이 명확해지지 않을 수 있다.

- 책임이 분산된 만큼 서비스 레이어가 간단해진다.

 

2. 일부 편의 메서드(update , setter)만 허용한다.

- 변경이 가능한 일부 필드만 열어두어 외부 변경 위험을 최소화할 수 있다.

- 여전히 엔티티의 책임을 넘어선다.

 

3. (가장 보수적)생성자와 필드만 허용한다.

- 엔티티 변환을 위한 로직으로 이해관계에 있는 클래스들이 뚱뚱해진다.

- 책임이 명확해진다.

 

도움을 받은 곳

https://www.inflearn.com/questions/30076/jpa-create-%EB%B0%8F-update-%EC%8B%9C-dto%EC%97%90%EC%84%9C-entity-%EB%B3%80%ED%99%98%EB%B0%A9%EC%8B%9D

 

jpa create 및 update 시 dto에서 entity 변환방식 - 인프런 | 질문 & 답변

안녕하세요 정말 유익한 강의 잘듣고 있고요 항상 친절한 답변에 감사함을 느낍니다.1.create시 createDto로 서비스로 넘어 온다면 아래에 방법중 어떤게 유지보수와 같은 측면에서 가장 나은 선택

www.inflearn.com