This is my first question, so please feel free to correct anything that I missed writing this question:)
I am having trouble with using the @Bulider with my DTO objects. I have an abstract class "EventDTO" inherited by a class type "CreateTaskLogDTO".
I have two constructors each on both classes. The constructors inside the CreateTaskLogDTO inherits the ones inside the EventDTO.
strangely, the constructor annotated with the
@Builder(builderMethodName = "buildWithSpecificParamsNoID")
works properly, but the one with
@Builder(builderMethodName = "buildWithOperationStringID")
fails to instantiate the following fields : String OperationString, Long id
Source code for EventDTO (parent class)
package com.wwme.wwme.log.domain.DTO;
import com.wwme.wwme.group.domain.Group;
import com.wwme.wwme.log.domain.OperationType;
import com.wwme.wwme.task.domain.Task;
import com.wwme.wwme.user.domain.User;
import lombok.*;
import lombok.experimental.SuperBuilder;
import java.time.LocalDateTime;
@Getter
@Setter
public abstract class EventDTO {
public EventDTO(Long id, User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, String operationString, Task task) {
this.id = id;
this.user = user;
this.group = group;
this.operationTypeEnum = operationTypeEnum;
this.operationTime = operationTime;
this.operationString = operationString;
this.task = task;
}
public EventDTO(User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, Task task) {
this.user = user;
this.group = group;
this.operationTypeEnum = operationTypeEnum;
this.operationTime = operationTime;
this.task = task;
}
protected Long id;
protected User user;
protected Group group;
protected Task task;
protected OperationType operationTypeEnum;
protected LocalDateTime operationTime;
protected String operationString;
//Calculate Operation String based on given parameters
public abstract void setOperationStr();
@Override
public String toString() {
return "EventDTO{" +
"id=" + id +
", user=" + user.getNickname() +
", group=" + group.getGroupName() +
", task=" + task.getTaskName() +
", operationTypeEnum=" + operationTypeEnum +
", operationTime=" + operationTime +
", operationString='" + operationString + '\'' +
'}';
}
//set specific fields for
public abstract void setSpecificFields();
public abstract String convertToString();
}
Source code for CreateTaskLogDTO (child class)
package com.wwme.wwme.log.domain.DTO;
import com.wwme.wwme.group.domain.Group;
import com.wwme.wwme.log.domain.OperationType;
import com.wwme.wwme.task.domain.Task;
import com.wwme.wwme.user.domain.User;
import lombok.*;
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
@Slf4j
@Getter
public class CreateTaskLogDTO extends EventDTO{
private String newTaskName;
@Builder(builderMethodName = "buildWithSpecificParamsNoID")
public CreateTaskLogDTO(User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, String newTaskName, Task task) {
super(user, group, operationTypeEnum, operationTime, task);
this.newTaskName = newTaskName;
setOperationStr();
}
@Builder(builderMethodName = "buildWithOperationStringID") //buildWithOperationStringID
public CreateTaskLogDTO(Long id, User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, String operationString, Task task) {
super(id, user, group, operationTypeEnum, operationTime, operationString, task);
setSpecificFields();
}
@Override
public String toString() {
return super.toString() + "CreateTaskLogDTO{" +
"newTaskName='" + newTaskName + '\'' +
", operationString='" + operationString + '\'' +
'}';
}
@Override
public void setOperationStr() {
this.operationString = newTaskName;
}
@Override
public void setSpecificFields() {
this.newTaskName = this.getOperationString();
}
@Override
public String convertToString() {
log.info(this.getUser().getNickname());
log.info(this.getNewTaskName());
return "\"" + this.getUser().getNickname() + "\" 님이 " + "\"" + this.getNewTaskName() +"\""
+ "과제를 생성하였습니다.";
}
}
Thanks!
I tried to running test codes to properly identify the problem.
This is the test that does not work (using the buildWithOperationStringID builder method) it fails to set up the fields : Id and OperationString. everything else sets up fine.
@Test
void createTaskLogDTO_builder_withID_test(){
String operationString = "Task1";
LocalDateTime now = LocalDateTime.now();
when(mockTask.getTaskName()).thenReturn("Task1");
when(mockUser.getNickname()).thenReturn("User1");
when(mockGroup.getGroupName()).thenReturn("Group1");
CreateTaskLogDTO createTaskLogDTO = CreateTaskLogDTO.buildWithOperationStringID()
.id(1L)
.task(mockTask)
.user(mockUser)
.group(mockGroup)
.operationString(operationString)
.operationTime(now)
.operationTypeEnum(OperationType.CREATE_TASK)
.build();
assertEquals(createTaskLogDTO.getId(),1L);
assertEquals(createTaskLogDTO.getTask().getTaskName(),mockTask.getTaskName());
assertEquals(createTaskLogDTO.getUser().getNickname(),mockUser.getNickname());
assertEquals(createTaskLogDTO.getGroup().getGroupName(),mockGroup.getGroupName());
assertEquals(createTaskLogDTO.getOperationTime(),now);
assertEquals(createTaskLogDTO.getOperationTypeEnum(),OperationType.CREATE_TASK);
assertEquals(operationString,createTaskLogDTO.getOperationString());
}
And this is the test of the builder method that works (buildWithSpecificParamsNoID) It properly sets all fields.
@Test
void createTaskLogDTO_build_withoutID_test(){
when(mockTask.getTaskName()).thenReturn("Task1");
when(mockUser.getNickname()).thenReturn("User1");
when(mockGroup.getGroupName()).thenReturn("Group1");
String operationString = "Task1";
LocalDateTime now = LocalDateTime.now();
CreateTaskLogDTO createTaskLogDTO = CreateTaskLogDTO.buildWithSpecificParamsNoID()
.task(mockTask)
.user(mockUser)
.group(mockGroup)
.operationTime(now)
.operationTypeEnum(OperationType.CREATE_TASK)
.newTaskName(mockTask.getTaskName())
.build();
assertEquals(createTaskLogDTO.getTask().getTaskName(),mockTask.getTaskName());
assertEquals(createTaskLogDTO.getUser().getNickname(),mockUser.getNickname());
assertEquals(createTaskLogDTO.getGroup().getGroupName(),mockGroup.getGroupName());
assertEquals(createTaskLogDTO.getOperationTime(),now);
assertEquals(createTaskLogDTO.getOperationTypeEnum(),OperationType.CREATE_TASK);
assertEquals(operationString,createTaskLogDTO.getOperationString());
assertEquals(mockTask.getTaskName(),createTaskLogDTO.getNewTaskName());
}
I think this is because both @Builder
tries to generate a builder class with the same name. Only one of them successfully generates this, and the other would see that an existing builder class already exists, and does not generate the builder class again.
In addition to having different builder method names, the two @Builder
annotations should also have different builderClassName
s:
@Builder(
builderMethodName = "buildWithSpecificParamsNoID",
builderClassName = "SpecificParamsNoIDBuilder"
)
public CreateTaskLogDTO(User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, String newTaskName, Task task) {
...
}
@Builder(
builderMethodName = "buildWithOperationStringID",
builderClassName = "OperationStringIDBuilder"
)
public CreateTaskLogDTO(Long id, User user, Group group, OperationType operationTypeEnum, LocalDateTime operationTime, String operationString, Task task) {
...
}