Несколько конструкторов, аннотированных Lombok @Builder, вызывают проблему?

Это мой первый вопрос, поэтому, пожалуйста, не стесняйтесь исправлять все, что я пропустил при написании этого вопроса :)

У меня возникли проблемы с использованием @Bulider с моими объектами DTO. У меня есть абстрактный класс «EventDTO», унаследованный типом класса «CreateTaskLogDTO».

У меня есть два конструктора в обоих классах. Конструкторы внутри CreateTaskLogDTO наследуют конструкторы внутри EventDTO.

как ни странно, конструктор снабжен аннотацией
@Builder(builderMethodName = "buildWithSpecificParamsNoID") работает правильно, но тот, у которого @Builder(builderMethodName = "buildWithOperationStringID") не удается создать экземпляр следующих полей: String OperationString, Long 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());

    }

какую версию Lombok вы используете? Я попробовал то же самое, но в основном классе все работало как положено.

Sayan Bhattacharya 14.07.2024 13:20
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
1
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, это потому, что оба @Builder пытаются создать класс-строитель с тем же именем. Только один из них успешно генерирует это, а другой увидит, что существующий класс строителя уже существует, и не будет генерировать класс строителя снова.

Помимо разных названий методов компоновщика, две аннотации @Builder также должны иметь разные builderClassName:

@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) {
    ...
}

Это сработало :) Теперь мне не нужно переделывать весь проект. Большое спасибо!!

Doh Kun Lee sanity 14.07.2024 13:56

Другие вопросы по теме