[Spring boot] 상속 관계가 있는 Entity에 @Builder 적용시 이슈

Byuk_mm·2022년 9월 4일
0

Spring Boot Development

목록 보기
4/13
post-thumbnail
post-custom-banner

Spring Boot 개발 중 학습이 필요한 내용을 정리하고,
트러블 슈팅 과정을 기록하는 포스팅입니다.




✅ Background

Lombok 라이브러리@Builder 어노테이션는 정말 많이 사용하는 어노테이션입니다.
이번 이슈는 상속 관계가 있는 Enitity에서 @Builder 어노테이션을 사용하는데서 발생합니다.


📌 TextMemoState Entity

아래의 TextMemoState EntityDynamoDBRedis에서 활용되는 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

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;
    }
}



✅ Problem

위의 Entity 클래스를 활용하면서 아래와 같은 오류가 발생했습니다.
오류 메세지에서도 @Builder 어노테이션을 활용하는데에서 오류가 발생했다고 말하고 있습니다.


 error: builder() in TextMemoStateLatest cannot hide builder() in TextMemoState
    @Builder
    ^
  return type TextMemoStateLatestBuilder is not compatible with TextMemoStateBuilder




✅ Solution

해당 문제는 상속 관계가 있는 Entity에 @Builder 어노테이션을 활용할 때 발생하는 문제였습니다.

문제가 발생한 이유는 @Builder 어노테이션을 사용한 초기화 시에,
자식 클래스에서 부모 클래스의 멤버 변수를 발견하지 못하며, 자식 클래스를 통해서 부모 멤버 변수를 초기화하지 못하기 때문에 발생하는 문제입니다.

이 때 사용하는 어노테이션이 @SuperBuilder 어노테이션 입니다.

@SuperBuilder 어노테이션은 부모 객체를 상속받는 자식 객체를 만들 때, 부모 객체의 필드값도 지정할 수 있게 해줍니다.

@SuperBuilder 어노테이션을 활용해서 위의 Entity를 다음과 같이 바꿀 수 있습니다!


📌 TextMemoStateHistory 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;
    }
}

📌 TextMemoStateHistory Entity

@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;
    }
}
profile
어디야 벽벽 / 블로그 이전 -> byuk.dev
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 12월 25일

superBuilder 라는 것도 있군요

답글 달기