[spring] @SuperBuilder 적용에서 발생한 문제와 해결
현재 진행 중인 프로젝트에서 @SuperBuilder
를 적용하며 문제상황이 발생하였고, 해결과정을 정리해보려 한다.
❓문제상황
문제 상황의 엔티티 구조는 다음과 같았다.
BaseEntity
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime modifiedAt;
}
Parent
@Getter
@SuperBuilder
@MappedSuperclass
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public abstract class Parent extends BaseEntity {
private String a;
}
Child
@Entity
@Getter
@SuperBuilder
@NoArgsConstructor
public class Child extends Parent {
private String b;
}
Child
엔티티는 Parent
엔티티를 상속받고, Parent
엔티티는 BaseEntity
를 상속받는다.
이 상황에서 Child
엔티티에 빌더 패턴을 생성하기 위해 Child
와 Parent
에 @SuperBuilder
애너테이션을 추가해 주었더니 아래와 같은 에러가 발생했다.
https://stackoverflow.com/questions/59626796/lomboks-superbuilder-error-java-cannot-find-symbol
Lombok's @SuperBuilder - Error java: cannot find symbol
I've been using Lombok with IntelliJ for a while now. I have installed newest (v. 0.28) Lombok plugin, enabled annotation processing and added a Lombok dependency (v. 1.18.10) in pom.xml. It all wo...
stackoverflow.com
위 stackoverflow 사이트에서 해당 오류와 관련된 해결책으로 BaseEntity
에도 @SuperBuilder
를 추가하는 방법이 있었다.
하지만 위 BaseEntity
에는 Id와 생성시간, 수정시간 등 빌더패턴에 포함시키고 싶지 않은 필드들이 존재 하였고 다른 방법을 생각하게 되었다.
📌해결방법
생성자에 @SuperBuilder
를 붙이는 방법도 생각해 보았지만 해당 애너테이션은 생성자에는 적용할 수 없었다.
결국 @SuperBuilder
를 포기하고 다음과 같은 방법으로 Child
엔티티의 빌더를 생성했다.
@Entity
@Getter
@NoArgsConstructor
public class Child extends Parent {
private String b;
@Builder
public Child(String a) {
super(a);
this.rating = rating;
}
}
Parent
를 상속받는 엔티티에 위와 같이 빌더를 적용할 생성자를 직접 생성해 주어야 했지만 BaseEntity의 필드 값이 엔티티 객체의 초기화에 이용되는 상황을 방지할 수 있었다.
🧐테스트 코드
@Test
void childBuilderTest() {
Child child = Child.builder()
.a("parent field")
.b("child field")
.build();
em.persist(child);
}
실제 엔티티로 테스트한 결과는 아래와 같다