代码之家  ›  专栏  ›  技术社区  ›  Doh Kun Lee sanity

使用Lombok@Builder注释的多个构造函数会导致问题吗?

  •  1
  • Doh Kun Lee sanity  · 技术社区  · 1 年前

    这是我的第一个问题,所以请随时纠正我在写这个问题时遗漏的任何内容:)

    我在将@Bulider与我的DTO对象一起使用时遇到了问题。 我有一个抽象类” 事件DTO “由类类型继承” CreateTaskLogDTO ".

    我在两个班上都有两个构造函数。内部施工人员 CreateTaskLogDTO 继承内部的那些 事件DTO .

    奇怪的是,构造函数用
    @构建器(builderMethodName=“buildWithSpecificParamsNoID”) 工作正常,但与 @构建器(builderMethodName=“buildWithOperationStringID”) 无法实例化以下字段:字符串操作字符串、长id

    EventDTO(父类)的源代码

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

    CreateTaskLogDTO(子类)的源代码

    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() +"\""
                    + "과제를 생성하였습니다.";
    
        }
    
    
    }
    
    

    谢谢

    我试图运行测试代码来正确识别问题。

    这是不起作用的测试(使用 buildWithOperationStringID 建设者法) 它无法设置字段:Id和OperationString。其他一切都设置得很好。

       @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());
        }
    
    

    这是对构建器方法有效性的测试(buildWithSpecificParamsNoID) 它正确设置了所有字段。

        @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());
    
        }
    
    
    1 回复  |  直到 1 年前
        1
  •  2
  •   Sweeper    1 年前

    我认为这是因为两者 @Builder 尝试生成同名的构建器类。其中只有一个成功生成了这个,另一个会看到现有的构建器类已经存在,并且不会再次生成构建器类。

    除了具有不同的构建器方法名称外 建设者 注释也应该有不同的 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) {
        ...
    }