@Default 빌더 기본값 적용

2024. 5. 28. 01:01· Today I Learned

java.lang.NullPointerException: Cannot invoke "com.keb.kebsmartfarm.entity.Plants.hasGrowingPlant()" because "this.plants" is null

일급 컬렉션 적용하면서 plants에서 현재 키우는 식물이 있는지 확인하는 hasPlant메서드를 실행하는데 문제가 생겼다.

아무래도 @Builder나 @NoArgsConstructor 중에 문제가 있는 것 같아, 빈 생성자에 new Plants()로 직접 삽입해줬다. 그런데도 문제가 있는 거 보니 @Builder 문제가 맞는 것 같다.

이 글을 참고해 생성된 Builder 코드를 직접 살펴보았다.

public static class ArduinoKitBuilder {
private Long kitNo;
private ReleasedKit releasedKit;
private String deviceName;
private String serialNum;
private LocalDateTime date;
private User user;
private Long userSeqNum;
private Plants plants;
private List<SensorData> sensorDataList;
ArduinoKitBuilder() {
}
public ArduinoKitBuilder kitNo(final Long kitNo) {
this.kitNo = kitNo;
return this;
}
public ArduinoKitBuilder releasedKit(final ReleasedKit releasedKit) {
this.releasedKit = releasedKit;
return this;
}
public ArduinoKitBuilder deviceName(final String deviceName) {
this.deviceName = deviceName;
return this;
}
public ArduinoKitBuilder serialNum(final String serialNum) {
this.serialNum = serialNum;
return this;
}
public ArduinoKitBuilder date(final LocalDateTime date) {
this.date = date;
return this;
}
@JsonIgnore
public ArduinoKitBuilder user(final User user) {
this.user = user;
return this;
}
public ArduinoKitBuilder userSeqNum(final Long userSeqNum) {
this.userSeqNum = userSeqNum;
return this;
}
@JsonIgnore
public ArduinoKitBuilder plants(final Plants plants) {
this.plants = plants;
return this;
}
public ArduinoKitBuilder sensorDataList(final List<SensorData> sensorDataList) {
this.sensorDataList = sensorDataList;
return this;
}
public ArduinoKit build() {
return new ArduinoKit(this.kitNo, this.releasedKit, this.deviceName, this.serialNum, this.date, this.user, this.userSeqNum, this.plants, this.sensorDataList);
}
public String toString() {
return "ArduinoKit.ArduinoKitBuilder(kitNo=" + this.kitNo + ", releasedKit=" + this.releasedKit + ", deviceName=" + this.deviceName + ", serialNum=" + this.serialNum + ", date=" + this.date + ", user=" + this.user + ", userSeqNum=" + this.userSeqNum + ", plants=" + this.plants + ", sensorDataList=" + this.sensorDataList + ")";
}
}

직접 살펴보니 @Builder 어노테이션은 클래스의 기본 생성자를 사용하지 않고 비어있는 빌더 클래스에서 매개변수로 받은 필드들을 채워나가는 형식으로 되어있는 것을 확인할 수 있었다. 그래서 기본 생성자로 채워넣든 필드를 초기화하든 관계 없이 매개변수로 넣어주지 않으면 채워지지 않는다.

아두이노 키트로 변환할 때 필요한 plants 값을 넣어주지 않았기 때문에 발생한 문제였다. 그래서 기본값을 넣어줘야 하는데 이 글을 참고해서 @Default 어노테이션으로 기본값을 넣어줬다. 그리고 직접 @Default 를 넣었을 때 생성되는 코드를 확인해봤다.

public class ArduinoKit {
...
private Plants plants;
...
private static Plants $default$plants() { return new Plants(); }
public static class ArudinoKitBuilder {
...
private boolean plants$set;
private Plants plant$value;
...
@JsonIgnore
public ArduinoKitBuilder plants(final Plants plants) {
this.plants$value = plants;
this.plants$set = true;
return this;
}
public ArduinoKit build() {
Plants plants$value = this.plants$value;
if (!this.plants$set) {
plants$value = ArduinoKit.$default$plants();
}
return new ArduinoKit(this.kitNo, this.releasedKit, this.deviceName, this.serialNum, this.date, this.user, this.userSeqNum, plants$value, this.sensorDataList);
}
}
}

직접 확인해보니 ArduinoKitBuilder 내부에 변수가 할당이 되었는지 확인하는 $##$set 이 boolean 으로 할당되어 있다. plants 메서드로 직접 plant$value를 할당하면 설정이 되었다는 의미인 true 로 둔다.

이후 build 메서드에서 set이 false 일 경우에만 $default$plants 메서드로 새로 생성해서 할당한다.

결론적으로 해결은 했다. @Builder 역시 남들이 다 쓰니까 나 역시도 관습적으로 사용했는데 빌더가 어떻게 작용하는지와 어떤 추가 어노테이션이 있는지 몰라서 조금 헤멨었다. 그리고 빌더를 사용하면 당연히 기본 생성자를 사용해서 쓸 것이라고 생각했는데 아예 내부 정적 클래스에서 새로 값을 추가해가면서 변환하는 것이였다. 역시 뭐든 잘 알고 사용하지 않으면 탈이난다..

 

참고

[intelliJ] lombok 생성 코드 확인하기

Lombok @Builder 사용 시 기본값 지정 방법

'Today I Learned' 카테고리의 다른 글

Mermaid ERD 문법  (1) 2024.12.02
CSRF 토큰 확인 불가 문제 해결  (0) 2024.06.29
필터에 @Component 등록 시 자동 등록  (0) 2024.06.28
'Today I Learned' 카테고리의 다른 글
  • Mermaid ERD 문법
  • CSRF 토큰 확인 불가 문제 해결
  • 필터에 @Component 등록 시 자동 등록
greatwhite
greatwhite
우직하게greatwhite 님의 블로그입니다.
greatwhite
우직하게
greatwhite
전체
오늘
어제
  • 분류 전체보기
    • Projects
      • 스위프] Woory
    • Python
    • Java
      • Spring
    • JPA
    • Problem Solving
      • 백준
      • 프로그래머스
    • Today I Learned

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바
  • 오블완
  • pigeonhole principle
  • Mermaid
  • vi
  • knapsack
  • Java
  • dp
  • @default
  • backtracking
  • 백준
  • 파이썬
  • dfs
  • erd 문법
  • 비트마스킹
  • 프로그래머스
  • math
  • python
  • MVC
  • sql
  • 다익스트라
  • BFS
  • implementation
  • JPA
  • 롬복
  • 티스토리챌린지
  • spring
  • 스프링
  • 그리디
  • Euclidean

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
greatwhite
@Default 빌더 기본값 적용
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.