Optional을 필드타입으로 사용하는 것을 지양하자

쭈·2023년 4월 18일
0

에러

목록 보기
3/9

dto의 Optional 필드와 json 파싱 에러

Dto

import java.util.Date;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class ChallengeDto {
	@Getter
	@NoArgsConstructor
	@AllArgsConstructor
	public static class Create {
		
		(((생략)))

		private Optional<Challenger> friends;

	}
	@Getter
	@NoArgsConstructor
	@AllArgsConstructor
	public static class Challenger{ 
		String nickname;
		String phone;
	}

}

DTO 중 json array를 받는 friends에서 다음과 같은 오류가 발생했다.

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type app.todoit.domain.challenge.dto.ChallengeDto$Challenger from Array value (token JsonToken.START_ARRAY); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type app.todoit.domain.challenge.dto.ChallengeDto$Challenger from Array value (token JsonToken.START_ARRAY) at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 7, column: 14] (through reference chain: app.todoit.domain.challenge.dto.ChallengeDto$Create["friends"])]

List<Challenger> friendsOptional로 바꾼 뒤 발생했다.

현재 구현하고 있는 로직 상 request json 중 friends 데이터는 필수데이터가 아니였다.

if(request.getFriends().isPresent()){
			request.getFriends().stream()
				.map(f -> {
					Optional<User> newUser = userRepository.findByPhone(f.getPhone());
					return inviteChallengers(newChallenge, newUser.get());
				})
				.forEach(challengerRepository::save);
		}

다음과 같이 데이터가 존재할 경우 isPresent()를 통해 로직을 편리하게 처리하기 위해 optional로 변경했었는데..
(지금 생각해보니 그냥 list의 사이즈로 체크하면 되는 부분인 것 같다)

인터넷에 dto에서 optional 사용법과 관련된 레퍼런스가 많기 때문에 ObjectMapper를 통해서 읽어오면 오류가 해결될 것 같았다.

그러나, 검색 도중 해당 오류와 별개로 Optional를 필드변수타입으로 사용하는 것을 권장하지 않고 리턴타입으로 사용해야된다는 것을 알게됐다.

Optional을 필드타입으로 사용하는 것을 권장하지 않는 이유

  1. 우선 Optional을 만든 사람이 애초에 리턴 타입으로 사용하도록 설계했다.
    (이 이유만으로 거의 충분한게 아닐까싶다.)
    메소드 상에서 반환 타입이 null일 경우, null값을 반환하면 오류가 발생할 가능성이 높아지기 때문에 Optional을 사용하도록 한다.
  2. 불필요하게 객체를 Wrapping하므로 생산성이 떨어진다.


(친절한 우리의 인텔리제이는 경고 느낌으로 알려준다.. ^.^)

profile
🌱

0개의 댓글