DTO → Entity 변환과 Entity → DTO 변환을 좀 더 편하게 하기 위해 ModelMapper를 도입하려 했으나, Setter를 사용해야 하는 상황에 직면했다.
Setter를 사용할 경우 여러 문제점이 뒤따라 올 수 있어 가급적이면 사용을 지양하고자 했으나, ModelMapper가 기본적으로 Public 메서드를 이용하여 변환을 수행하기 때문에 Setter를 열어주어야 하는 상황에 직면했다.
@Bean
public ModelMapper modelMapper() {
final ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PRIVATE);
return modelMapper;
}
ModelMapper의 필드 변환을 활성화하고, 필드 접근 제한자 레벨을 Private으로 변경하여 문제를 해결할 수 있었다.
이때, modelMapper의 내부 인자는 모두 object여야한다.
예를 들어, String을 넣으면 오류가 발생한다.
public class AccountCreationRequestDto {
@NotNull
private final Long profileId;
@NotBlank
@Email
private final String email;
@NotBlank
private final String password;
}
클라이언트의 요청 파라미터를 처리하기 위해 별도의 DTO를 정의해놓고, 필요한 시점에 ModelMapper를 이용해 Entity로 변환해서 사용하도록 설계를 하였다.
@Entity
public class Account extends Timestamp {
public static final int VERIFICATION_CODE_MAX_LENGTH = 6;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JoinColumn(name = "profile_id", nullable = false)
@OneToOne(fetch = FetchType.LAZY)
private Profile profile;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private Boolean verificationState;
@Column(length = VERIFICATION_CODE_MAX_LENGTH)
private String verificationCode;
}
하지만 Account
Entity의 verificationState
필드처럼 반드시 설정해 주어야 하지만 DTO에는 없는 경우가 있어, ModelMapper를 이용해 변환한 이후 Setter를 이용해 추가적으로 설정을 해주어야 하는 문제가 생겼다.
@Builder
public Account(final Long id, final Profile profile, final String email, final String password, final Boolean verificationState, final String verificationCode) {
setProfile(profile);
this.id = id;
this.email = email;
this.password = password;
this.verificationState = verificationState;
this.verificationCode = verificationCode;
}
void setProfile(final Profile profile) {
if (this.profile != null) {
this.profile.setAccount(null);
}
this.profile = profile;
if (profile != null) {
profile.setAccount(this);
}
}
Entity에 반드시 설정되어야 하는 필드지만 DTO에는 없어서 ModelMapper만으로는 해결되지 않는 경우, ModelMapper를 사용하는 대신 Builder 패턴을 이용하여 직접 설정해 주기로 하였다.
Organized by Igoc
https://velog.io/@hope1213/Setter-%EC%82%AC%EC%9A%A9%EC%9D%84-%EC%99%9C-%EC%A7%80%EC%96%91%ED%95%B4%EC%95%BC%ED%95%A0%EA%B9%8C
https://yooooonnf.tistory.com/2