MyShop 애플리케이션은 JPA를 이용해 **MySQL(RDB)**과 연동해 사용하고 있다. 이에 따라 도메인을 모델링을 해보자

Untitled

1. 엔티티 클래스 어노테이션 개선

엔티티 클래스를 작성할 때 다음과 같이 어노테이션을 많이 쓴다. 하지만 이 엔티티 클래스에 작성된 어노테이션은 몇가지 문제가 있다.

@Getter
**@Setter // 문제 1**
**@NoArgsConstructor // 문제 2**
@Builder
**@AllArgsConstructor // 문제3**
@Entity
public class ExampleEntity

1.1. @Setter 사용하지 않기

@Setter 어노테이션을 사용하게 되면 해당 필드의 값을 변경할 수 있게 되는데, 이렇게 되면 필드의 값이 불변하게 되는 객체지향의 개념에 어긋나게 된다.

또 스프링에서는 JPA를 이용해 데이터를 관리하기 때문에 @Setter 어노테이션을 사용하게 되면 의도하지 않은 엔티티 값의 변경이 일어나게 될 수 있다. 특히 엔티티에 @Setter를 사용하면 변경이 발생했을 때 추적하기 힘들어진다.

그렇기 때문에 값 변경이 필요하다면 의미 있는 메서드를 생성해 사용하는 것이 좋다.

1.2. @NoArgsConstructor의 접근 제어자 Protected로 변경

@NoArgsConstructor 어노테이션을 사용해 파라미터가 없는 생성자를 만들게 되는데, 이 생성자는 외부에서 호출될 필요가 없어 접근 제어자를 Protected로 변경하는 것이 좋다.

이러면 해당 클래스를 상속받은 하위 클래스에서만 사용할 수 있어 안정성이 높아지게 된다.

즉 무분별한 객체 생성에 대해 한 번 더 체크할 수 있게 된다.

//@NoArgsConstructor(access = AccessLevel.PROTECTED) 
ExampleEntity exampleEntity = new ExampleEntity(); **//컴파일 에러**

1.3. @AllArgsConstructor는 사용하지 않기

@AllArgsConstructor 어노테이션을 사용하여 모든 필드를 포함한 생성자를 만들게 되는데, 이 생성자는 JPA에서 사용되는 기본 생성자와 충돌할 수 있어 사용하지 않는 것이 좋다.

만약 **@AllArgsConstructor**를 작성하게 되면 인스턴스 멤버의 선언 순서에 영향을 받아 필드의 순서를 바꾸게 되면 생성자의 입력 값 순서도 바뀌게 되어 검출되지 않는 치명적인 오류를 발생시킬 수 있다.

이를 해결하기 위해 생성자에 @Builder를 사용@AllArgsConstructor를 사용하지 않도록 해야한다.

1.4. @ToString 사용 시 연관관계 엔티티 필드 제거