Spring Boot 개발 중 학습이 필요한 내용을 정리하고,
트러블 슈팅 과정을 기록하는 포스팅입니다.
Lombok 라이브러리
의 @Builder 어노테이션
는 정말 많이 사용하는 어노테이션입니다.
이번 이슈는 상속 관계가 있는 Enitity
에서 @Builder 어노테이션
을 사용하는데서 발생합니다.
아래의 TextMemoState Entity
는 DynamoDB
와 Redis
에서 활용되는 Entity
입니다.
일반적인 @Builder 어노테이션
을 활용하는 것 처럼 생성자 부분에 @Builder 어노테이션
을 활용한 것을 볼 수 있습니다.
아래 코드의 DynamoDB와 관련된 어노테이션은 이번 포스팅 주제와 연관이 있지 않습니다.
@Getter
@RedisHash(value = "text_memo_state")
@DynamoDBDocument
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class TextMemoState {
@Id
@Indexed
@DynamoDBIgnore
private String id;
@DynamoDBIgnore
private UUID individualVideoId;
@DynamoDBAttribute(attributeName = "state_json")
protected String stateJson;
@DynamoDBAttribute(attributeName = "video_time")
@DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.S)
protected LocalTime videoTime;
@DynamoDBAttribute(attributeName = "created_at")
@DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.S)
protected LocalDateTime createdAt;
@Builder
public TextMemoState(String id,UUID individualVideoId, String stateJson, LocalTime videoTime, LocalDateTime createdAt) {
this.id = id;
this.individualVideoId = individualVideoId;
this.stateJson = stateJson;
this.videoTime = videoTime;
this.createdAt = createdAt;
}
}
TextMemoStateHistory Entity
는 위의 TextMemoState Entity
를 상속받는 Entity
입니다.
id와 individualVideoId를 부모 클래스와 똑같은 이름을 같게 설계했다는 특이점이 있지만, 일반적인 상속 관계와 똑같습니다.
부모 클래스와 비슷하게 생성자 부분에 @Builder 어노테이션
을 활용했습니다.
@Getter
@NoArgsConstructor()
@DynamoDBTable(tableName = "text_memo_state_history")
public class TextMemoStateHistory extends TextMemoState{
@DynamoDBRangeKey(attributeName="id")
private String id;
@DynamoDBHashKey(attributeName = "individual_video_id")
private UUID individualVideoId;
@Builder
public TextMemoStateHistory(String id, UUID individualVideoId, String stateJson, LocalTime videoTime, LocalDateTime createdAt) {
super(id, individualVideoId, stateJson, videoTime, createdAt);
this.id = id;
this.individualVideoId = individualVideoId;
}
}
위의 Entity 클래스를 활용하면서 아래와 같은 오류가 발생했습니다.
오류 메세지에서도 @Builder 어노테이션
을 활용하는데에서 오류가 발생했다고 말하고 있습니다.
error: builder() in TextMemoStateLatest cannot hide builder() in TextMemoState
@Builder
^
return type TextMemoStateLatestBuilder is not compatible with TextMemoStateBuilder
해당 문제는 상속 관계가 있는 Entity에 @Builder 어노테이션을 활용할 때 발생하는 문제였습니다.
문제가 발생한 이유는 @Builder 어노테이션을 사용한 초기화 시에,
자식 클래스에서 부모 클래스의 멤버 변수를 발견하지 못하며, 자식 클래스를 통해서 부모 멤버 변수를 초기화하지 못하기 때문에 발생하는 문제입니다.
이 때 사용하는 어노테이션이 @SuperBuilder 어노테이션 입니다.
@SuperBuilder 어노테이션은 부모 객체를 상속받는 자식 객체를 만들 때, 부모 객체의 필드값도 지정할 수 있게 해줍니다.
@SuperBuilder 어노테이션을 활용해서 위의 Entity를 다음과 같이 바꿀 수 있습니다!
@Getter
@RedisHash(value = "text_memo_state")
@DynamoDBDocument
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder // 추가
public class TextMemoState {
// .. 중략
// @Builder
public TextMemoState(String id,UUID individualVideoId, String stateJson, LocalTime videoTime, LocalDateTime createdAt) {
this.id = id;
this.individualVideoId = individualVideoId;
this.stateJson = stateJson;
this.videoTime = videoTime;
this.createdAt = createdAt;
}
}
@SuperBuilder // 추가
@Getter
@NoArgsConstructor()
@DynamoDBTable(tableName = "text_memo_state_history")
public class TextMemoStateHistory extends TextMemoState{
//.. 중략
// @Builder
public TextMemoStateHistory(String id, UUID individualVideoId, String stateJson, LocalTime videoTime, LocalDateTime createdAt) {
super(id, individualVideoId, stateJson, videoTime, createdAt);
this.id = id;
this.individualVideoId = individualVideoId;
}
}
superBuilder 라는 것도 있군요