일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- jpa
- Algorithm
- mysql
- java
- 완전탐색
- PYTHON
- 트러블슈팅
- 영속성 컨텍스트
- 알고리즘
- It
- CS
- nosql
- DFS
- 데이터베이스
- Data structure
- spring
- javascript
- 트랜잭션
- redis
- OS
- 프로그래머스
- 운영체제
- HTML
- Docker
- websocket
- BFS
- 자료구조
- db
- 백준
- CSS
- Today
- Total
If at first you don't succeed, try again
[트러블슈팅] DTO 필드 변수의 prefix 이슈 본문
* 문제 상황
중복을 확인하는 검증에서 Dto 클래스 필드의 변수를 isDuplicate로 지정을 했었다.
그 후 프론트와의 API 연동에서 response 부분을 확인해보니 isDuplicate가 아니라 duplicate로 표시가 되었다.
아래는 DTO 코드이다.
@Getter
@AllArgsConstructor
public class DuplicateCheckResponse {
private boolean isDuplicate;
}
여기서 기대되는 값은
{
"isDuplicate": false
}
인데 표시되는 값은
{
"duplicate": false
}
였다.
* 원인
원인은 lombok의 getter와 json을 직렬화 & 역직렬화하는 jackson 라이브러리에 있었다.
lombok 라이브러리의 공식 문서를 살펴보면,
You can annotate any field with @Getter and/or @Setter, to let lombok generate the default getter/setter automatically.
A default getter simply returns the field, and is named getFoo if the field is called foo(or isFoo if the field's type is boolean).
이라고 되어있다. 해석하면 lombok은 getFoo()와 같이 prefix로 get를 사용하는데,
boolean 자료형의 getter는 isFoo()처럼 prefix로 is를 사용한다고 되어있다.
한편, jackson 라이브러리는 json 객체의 직렬화 과정에서 getter와 setter를 이용한다.
getFoo()의 경우 get을 지우고, setFoo()의 경우에는 set을 지우는 것이다. 공식문서에는 이렇게 나와있다.
By default Jackson maps the fields of a JSON object to fields in a Java object by matching the names of the JSON field to the getter and setter methods in the Java object. Jackson removes the "get" and "set" part of the names of the getter and setter methods, and converts the first character of the remaining name to lowercase.
해석하면 기본적으로 Jackson은 JSON 객체의 필드를 Java 객체의 필드에 매핑하고,
JSON 필드의 이름을 Java 객체의 getter 및 setter 메서드와 일치시킨다.
그리고 Jackson은 getter 및 setter 메서드 이름에서 "get"과 "set" 부분을 제거하고, 나머지 이름의 첫 글자를 소문자로 변환한다.
따라서 lombok에 의해 isDuplicate는 getIsDuplicate가 아니라 isDuplicate로 만들어졌기 때문에
jackson 라이브러리가 prefix인 is를 지워서 duplicate가 표시된 것이다.
* 해결 방법
이를 해결하기 위해 primitive 타입인 boolean 대신 wrapper 클래스인 Boolean을 사용했다.
@Getter
@AllArgsConstructor
public class DuplicateCheckResponse {
private Boolean isDuplicate;
}
다만 Boolean은 클래스이기 때문에 null 값이 들어갈 수 있어 NPE가 발생할 가능성이 있다.
또한 boolean에 비해 메모리를 더 차지한다는 단점이 있다.
그렇지만 코드 상에서 null 값이 될 수 있는 상황은 없다.
* 대체 방안
다른 해결방안으로는 boolean 타입의 변수명을 is~로 짓지 않는 것이다.
isDelete→ deleted
isDuplicate→ duplicated
'개발 > 트러블슈팅' 카테고리의 다른 글
[트러블슈팅] 커서 기반 무한 스크롤의 댓글 수, 좋아요 수를 조회하는 쿼리에서 발생했던 성능 문제(feat. N+1) (0) | 2025.06.04 |
---|---|
[트러블슈팅] 엔티티에 @ToString 사용으로 인한 순환참조(feat. JPA) (0) | 2025.06.04 |
[트러블슈팅] 게시물 작성에서 사진 업로드 시 발생했던 문제 (1) | 2025.06.04 |
[트러블슈팅] Gradle 버전 문제 (0) | 2023.10.05 |