Невозможно отобразить вложенный список с помощью Mapstruct - во время теста он возвращает list = null

Я еще учусь, так что строго не судите)

Два вопроса: 1) Ошибка сопоставления - не устанавливает объект List в зеркальные объекты (в одном направлении список равен Null, в другом - за пределами длины 0) 2) Оптимизация отображения иерархии объектов

Кода во вставках получилось очень много, но я еще не совсем понял, что показывать ошибки не важно для анализа и показал все как есть, на всякий случай. Итак, есть начальная структура, подобная этой:

@MappedSuperclass
@Data
@NoArgsConstructor
public abstract class BusinessEntity {
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "id", updatable = false, nullable = false)
    private UUID id;
    @Column(updatable = false)
    @CreationTimestamp
    private LocalDateTime createdOn;
    @UpdateTimestamp
    private LocalDateTime modifiedOn;
    private LocalDateTime deletedOn;
    @NotNull
    private boolean SystemProtectedStatus = false;
    @NotNull
    private boolean SuspendedStatus = false;
    @NotNull
    private boolean blockedStatus = false;
    @NotNull
    private boolean deletedStatus = false;
    private LocalDateTime activeFrom;
    private LocalDateTime activeUntil;
}

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SystemRights extends BusinessEntity {

    @NotNull
    private String name;
    private String description;

    public SystemRights(@NotNull String name) {
        super();
        this.name = name;
    }
}

@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@NoArgsConstructor
public class UserRole extends BusinessEntity{

    @NotNull
    private String name;
    private String description;

    @ManyToMany
    @JoinTable(
            name = "rights_in_roles"
            , joinColumns = @JoinColumn(name = "right_id")
            , inverseJoinColumns = @JoinColumn (name = "role_id")
    )
    public List<SystemRights> systemRights;



    public UserRole(@NotNull String name) {
        this.name = name;
    }


    public List<SystemRights> getSystemRights() {
        if (systemRights == null)
            systemRights = new ArrayList<>();
        return systemRights;
    }

    public void addSystemRights(SystemRights newSystemRights) {
        if (newSystemRights == null)
            return;
        if (this.systemRights == null)
            this.systemRights = new ArrayList<>();
        this.systemRights.add(newSystemRights);
    }

    public void removeSystemRights(SystemRights oldSystemRights) {
        if (oldSystemRights == null)
            return;
        if (this.systemRights != null)
            this.systemRights.remove(oldSystemRights);
    }

    public void removeAllSystemRights() {
        if (systemRights != null)
            systemRights.clear();
    }
}

Я хочу сопоставить его с DTO следующим образом: (фактически один к одному)

@Data
public abstract class Dto {

    private String id;
    private String activeFrom;
    private String activeUntil;

    private boolean SystemProtectedStatus;
    private boolean SuspendedStatus;
    private boolean blockedStatus;
    private boolean deletedStatus;

    private String createdOn;
    //    private User createdBy;
    private String modifiedOn;
    //    private User modifiedBy;
    private String deletedOn;
//    private User deletedBy;
}

@Data
public class SystemRightsDto extends Dto{

    @NotNull
    private String name;
    private String description;
}

@Data
public class UserRoleDto extends Dto {

    @NotNull
    private String name;
    private String description;

    @NotNull
    public List<SystemRightsDto> systemRightsDto;
}

Для этого я сложил эти картографы ниже. - И вот первый вопрос: - как в MapStruct правильно унаследовать отображение от корневого объекта BusinessEntity, который является предком для всех объектов учета в системе и не страдать от копирования-вставки в каждый дочерний объект, как я здесь пострадал во время тренировки?

@Mapper
public interface UserRoleMapper {

    @Mapping(target = "id",
            expression = "java(getStringFromId(entity.getId()))")
    @Mapping(target = "activeFrom",
            expression = "java(getStringfromLDT(entity.getActiveFrom()))")
    @Mapping(target = "activeUntil",
            expression = "java(getStringfromLDT(entity.getActiveUntil()))")
    @Mapping(target = "createdOn",
            expression = "java(getStringfromLDT(entity.getCreatedOn()))")
    @Mapping(target = "modifiedOn",
            expression = "java(getStringfromLDT(entity.getModifiedOn()))")
    @Mapping(target = "deletedOn",
            expression = "java(getStringfromLDT(entity.getDeletedOn()))")
    UserRoleDto getDtoFromEntity(UserRole entity);



    @Mapping(target = "id",
            expression = "java(getIdFromString(dto.getId()))")
    @Mapping(target = "activeFrom",
            expression = "java(getLDTfromString(dto.getActiveFrom()))")
    @Mapping(target = "activeUntil",
            expression = "java(getLDTfromString(dto.getActiveUntil()))")
    @Mapping(target = "createdOn",
            expression = "java(getLDTfromString(dto.getCreatedOn()))")
    @Mapping(target = "modifiedOn",
            expression = "java(getLDTfromString(dto.getModifiedOn()))")
    @Mapping(target = "deletedOn",
            expression = "java(getLDTfromString(dto.getDeletedOn()))")

    UserRole getEntityFromDto(UserRoleDto dto);



    List<SystemRights> SystemRightsDtoToEnt (List<SystemRightsDto> dto);
    List<SystemRightsDto> SystemRightsEntToDto (List<SystemRights> entity);


    default LocalDateTime getLDTfromString(String string) {
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
        if (!isNull(string)) {
            return LocalDateTime.parse(string, formatter);
        } else {
            return null;
        }
    }
    default String getStringfromLDT(LocalDateTime ldt) {
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
        if (!isNull(ldt)) {
            return ldt.toString();
        } else {
            return null;
        }
    }
    default String getStringFromId(UUID id) {
        if (!isNull(id)) {
            return id.toString();
        } else {
            return null;
        }
    }
    default UUID getIdFromString(String id) {
        if (!isNull(id)) {
            return UUID.fromString(id);
        } else {
            return null;
        }
    }
}


@Mapper
public interface SystemRightsMapper {

    @Mapping(target = "id",
            expression = "java(getStringFromId(entity.getId()))")
    @Mapping(target = "activeFrom",
            expression = "java(getStringfromLDT(entity.getActiveFrom()))")
    @Mapping(target = "activeUntil",
            expression = "java(getStringfromLDT(entity.getActiveUntil()))")
    @Mapping(target = "createdOn",
            expression = "java(getStringfromLDT(entity.getCreatedOn()))")
    @Mapping(target = "modifiedOn",
            expression = "java(getStringfromLDT(entity.getModifiedOn()))")
    @Mapping(target = "deletedOn",
            expression = "java(getStringfromLDT(entity.getDeletedOn()))")
    SystemRightsDto getDtoFromEntity(SystemRights entity);


    @Mapping(target = "id",
            expression = "java(getIdFromString(dto.getId()))")
    @Mapping(target = "activeFrom",
            expression = "java(getLDTfromString(dto.getActiveFrom()))")
    @Mapping(target = "activeUntil",
            expression = "java(getLDTfromString(dto.getActiveUntil()))")
    @Mapping(target = "createdOn",
            expression = "java(getLDTfromString(dto.getCreatedOn()))")
    @Mapping(target = "modifiedOn",
            expression = "java(getLDTfromString(dto.getModifiedOn()))")
    @Mapping(target = "deletedOn",
            expression = "java(getLDTfromString(dto.getDeletedOn()))")
    SystemRights getEntityFromDto(SystemRightsDto dto);

    List<SystemRights> SystemRightsDtoToEnt (List<SystemRightsDto> dto);
    List<SystemRightsDto> SystemRightsEntToDto (List<SystemRights> entity);

    default LocalDateTime getLDTfromString(String string) {
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
        if (!isNull(string)) {
            return LocalDateTime.parse(string, formatter);
        } else {
            return null;
        }
    }
    default String getStringfromLDT(LocalDateTime ldt) {
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
        if (!isNull(ldt)) {
            return ldt.toString();
        } else {
            return null;
        }
    }
    default String getStringFromId(UUID id) {
        if (!isNull(id)) {
            return id.toString();
        } else {
            return null;
        }
    }
    default UUID getIdFromString(String id) {
        if (!isNull(id)) {
            return UUID.fromString(id);
        } else {
            return null;
        }
    }
}

Тест передачи SystemRights работает в обоих направлениях, но тест UserRole не проходит. Сам тест такой:

public class UserRoleMapperTest {
    private UserRoleMapper userRoleMapper = Mappers.getMapper(UserRoleMapper.class);

    @Test
    public void testEntityToDto(){

        String  testDateStr = "2021-04-05T12:53:16.173706900";
        LocalDateTime testDateLDT = LocalDateTime.parse(testDateStr);
        UUID uuidTest = UUID.fromString("c095ad9f-37d4-479f-b88d-17df04f2437b");

        UserRole e = new UserRole();
        e.setName("Admin");
        e.setDescription("Super");
        e.setId(uuidTest);
        e.setActiveFrom(testDateLDT);
        e.setActiveUntil(testDateLDT);
        e.setSystemProtectedStatus(true);
        e.setBlockedStatus(false);
        e.setSuspendedStatus(true);
        e.setDeletedStatus(false);
        e.setCreatedOn(testDateLDT);
        e.setDeletedOn(testDateLDT);
        e.setModifiedOn(testDateLDT);

        List<SystemRights> eList = new ArrayList<>();
        e.setSystemRights(eList);

        SystemRights sr1= new SystemRights("Create");
        SystemRights sr2= new SystemRights("Read");
        SystemRights sr3= new SystemRights("Delete");
        eList.add(sr1);
        eList.add(sr2);
        eList.add(sr3);

        System.out.println("Testing testEntityToDto:  Entity have");
        System.out.println(e);

        UserRoleDto d = userRoleMapper.getDtoFromEntity(e);

        assertEquals(d.getName(),e.getName());
        assertEquals(d.getDescription(),e.getDescription());
        assertEquals(d.getId(),"c095ad9f-37d4-479f-b88d-17df04f2437b");
        assertEquals(d.getActiveFrom(),"2021-04-05T12:53:16.173706900");
        assertEquals(d.getActiveUntil(), "2021-04-05T12:53:16.173706900");
        assertEquals(d.isSystemProtectedStatus(),e.isSystemProtectedStatus());
        assertEquals(d.isDeletedStatus(),e.isDeletedStatus());
        assertEquals(d.isBlockedStatus(),e.isBlockedStatus());
        assertEquals(d.isSuspendedStatus(),e.isSuspendedStatus());
        assertEquals(d.getCreatedOn(),"2021-04-05T12:53:16.173706900");
        assertEquals(d.getModifiedOn(),"2021-04-05T12:53:16.173706900");
        assertEquals(d.getDeletedOn(),"2021-04-05T12:53:16.173706900");

        assertEquals(d.getSystemRightsDto().get(0).toString(),e.getSystemRights().get(0).toString());
        assertEquals(d.getSystemRightsDto().get(1).toString(),e.getSystemRights().get(1).toString());
        assertEquals(d.getSystemRightsDto().get(2).toString(),e.getSystemRights().get(2).toString());

        assertEquals(d.getSystemRightsDto().toString(),e.getSystemRights().toString());

        System.out.println("Testing testEntityToDto:  Dto have");
        System.out.println(d);
    }

    @Test
    public void testDtoToEntity(){

        String  testDateStr = "2021-04-05T12:53:16.173706900";
        LocalDateTime testDateLDT = LocalDateTime.parse(testDateStr);
        UUID uuidTest = UUID.fromString("c095ad9f-37d4-479f-b88d-17df04f2437b");

        UserRoleDto  d = new UserRoleDto();
        d.setName("Create");
        d.setDescription("Desc");
        d.setId("c095ad9f-37d4-479f-b88d-17df04f2437b");
        d.setActiveFrom("2021-04-05T12:53:16.173706900");
        d.setActiveUntil("2021-04-05T12:53:16.173706900");
        d.setSystemProtectedStatus(true);
        d.setBlockedStatus(false);
        d.setSuspendedStatus(true);
        d.setDeletedStatus(false);
        d.setCreatedOn("2021-04-05T12:53:16.173706900");
        d.setDeletedOn("2021-04-05T12:53:16.173706900");
        d.setModifiedOn("2021-04-05T12:53:16.173706900");

        List<SystemRightsDto> eListDto = new ArrayList<>();
        d.setSystemRightsDto(eListDto);

        SystemRightsDto sr1= new SystemRightsDto();
        sr1.setName("Create");
        SystemRightsDto sr2= new SystemRightsDto();
        sr2.setName("Read");
        SystemRightsDto sr3= new SystemRightsDto();
        sr3.setName("Delete");
        eListDto.add(sr1);
        eListDto.add(sr2);
        eListDto.add(sr3);

        System.out.println("Testing testDtoToEntity:  Dto have");
        System.out.println(d);

        UserRole e = userRoleMapper.getEntityFromDto(d);

        assertEquals(e.getName(),d.getName());
        assertEquals(e.getDescription(),d.getDescription());
        assertEquals(e.getId(),uuidTest);
        assertEquals(e.getActiveFrom(),testDateLDT);
        assertEquals(e.getActiveUntil(),testDateLDT);
        assertEquals(e.isSystemProtectedStatus(),d.isSystemProtectedStatus());
        assertEquals(e.isDeletedStatus(),d.isDeletedStatus());
        assertEquals(e.isBlockedStatus(),d.isBlockedStatus());
        assertEquals(e.isSuspendedStatus(),d.isSuspendedStatus());
        assertEquals(e.getCreatedOn(),testDateLDT);
        assertEquals(e.getModifiedOn(),testDateLDT);
        assertEquals(e.getDeletedOn(),testDateLDT);

        assertEquals(e.getSystemRights().get(0).toString(),d.getSystemRightsDto().get(0).toString());
        assertEquals(e.getSystemRights().get(1).toString(),d.getSystemRightsDto().get(1).toString());
        assertEquals(e.getSystemRights().get(2).toString(),d.getSystemRightsDto().get(2).toString());

        assertEquals(e.getSystemRights().toString(),d.getSystemRightsDto().toString());

        System.out.println("Testing testDtoToEntity:  Entity have");
        System.out.println(e);
    }
}

Когда я запускаю тест «testEntityToDto», я получаю:

Тестирование testEntityToDto: Entity имеют UserRole (name = Admin, description = Super, systemRights = [SystemRights (name = Create, description = null), SystemRights (name = Read, description = null), SystemRights (name = Delete, description = null)])

java.lang.NullPointerException: невозможно вызвать «java.util.List.get (int)», поскольку возвращаемое значение «com.example.cparty.dto.UserRoleDto.getSystemRightsDto ()» равно null

в com.example.cparty.UserRoleMapperTest.testEntityToDto (UserRoleMapperTest.java:77)

Когда я запускаю тест "testDtoToEntity", я получаю:

Тестирование testDtoToEntity: Dto иметь UserRoleDto (name = Create, description = Desc, systemRightsDto = [SystemRightsDto (name = Create, description = null), SystemRightsDto (name = Read, description = null), SystemRightsDto (name = Delete, description = null)])

java.lang.IndexOutOfBoundsException: индекс 0 выходит за пределы для длины 0

at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at com.example.cparty.UserRoleMapperTest.testDtoToEntity(UserRoleMapperTest.java:149)

Сам MapStrakt сгенерировал следующий код: (в нем я не видел, как он устанавливает List для целевого объекта)

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2021-04-06T11:03:58+0300",
    comments = "version: 1.4.2.Final, compiler: javac, environment: Java 11.0.6 (JetBrains s.r.o)"
)
public class UserRoleMapperImpl implements UserRoleMapper {

    @Override
    public UserRoleDto getDtoFromEntity(UserRole entity) {
        if ( entity == null ) {
            return null;
        }

        UserRoleDto userRoleDto = new UserRoleDto();

        userRoleDto.setSystemProtectedStatus( entity.isSystemProtectedStatus() );
        userRoleDto.setSuspendedStatus( entity.isSuspendedStatus() );
        userRoleDto.setBlockedStatus( entity.isBlockedStatus() );
        userRoleDto.setDeletedStatus( entity.isDeletedStatus() );
        userRoleDto.setName( entity.getName() );
        userRoleDto.setDescription( entity.getDescription() );

        userRoleDto.setId( getStringFromId(entity.getId()) );
        userRoleDto.setActiveFrom( getStringfromLDT(entity.getActiveFrom()) );
        userRoleDto.setActiveUntil( getStringfromLDT(entity.getActiveUntil()) );
        userRoleDto.setCreatedOn( getStringfromLDT(entity.getCreatedOn()) );
        userRoleDto.setModifiedOn( getStringfromLDT(entity.getModifiedOn()) );
        userRoleDto.setDeletedOn( getStringfromLDT(entity.getDeletedOn()) );

        return userRoleDto;
    }

    @Override
    public UserRole getEntityFromDto(UserRoleDto dto) {
        if ( dto == null ) {
            return null;
        }

        UserRole userRole = new UserRole();

        userRole.setSystemProtectedStatus( dto.isSystemProtectedStatus() );
        userRole.setSuspendedStatus( dto.isSuspendedStatus() );
        userRole.setBlockedStatus( dto.isBlockedStatus() );
        userRole.setDeletedStatus( dto.isDeletedStatus() );
        userRole.setName( dto.getName() );
        userRole.setDescription( dto.getDescription() );

        userRole.setId( getIdFromString(dto.getId()) );
        userRole.setActiveFrom( getLDTfromString(dto.getActiveFrom()) );
        userRole.setActiveUntil( getLDTfromString(dto.getActiveUntil()) );
        userRole.setCreatedOn( getLDTfromString(dto.getCreatedOn()) );
        userRole.setModifiedOn( getLDTfromString(dto.getModifiedOn()) );
        userRole.setDeletedOn( getLDTfromString(dto.getDeletedOn()) );

        return userRole;
    }

    @Override
    public List<SystemRights> SystemRightsDtoToEnt(List<SystemRightsDto> dto) {
        if ( dto == null ) {
            return null;
        }

        List<SystemRights> list = new ArrayList<SystemRights>( dto.size() );
        for ( SystemRightsDto systemRightsDto : dto ) {
            list.add( systemRightsDtoToSystemRights( systemRightsDto ) );
        }

        return list;
    }

    @Override
    public List<SystemRightsDto> SystemRightsEntToDto(List<SystemRights> entity) {
        if ( entity == null ) {
            return null;
        }

        List<SystemRightsDto> list = new ArrayList<SystemRightsDto>( entity.size() );
        for ( SystemRights systemRights : entity ) {
            list.add( systemRightsToSystemRightsDto( systemRights ) );
        }

        return list;
    }

    protected SystemRights systemRightsDtoToSystemRights(SystemRightsDto systemRightsDto) {
        if ( systemRightsDto == null ) {
            return null;
        }

        SystemRights systemRights = new SystemRights();

        systemRights.setId( getIdFromString( systemRightsDto.getId() ) );
        systemRights.setCreatedOn( getLDTfromString( systemRightsDto.getCreatedOn() ) );
        systemRights.setModifiedOn( getLDTfromString( systemRightsDto.getModifiedOn() ) );
        systemRights.setDeletedOn( getLDTfromString( systemRightsDto.getDeletedOn() ) );
        systemRights.setSystemProtectedStatus( systemRightsDto.isSystemProtectedStatus() );
        systemRights.setSuspendedStatus( systemRightsDto.isSuspendedStatus() );
        systemRights.setBlockedStatus( systemRightsDto.isBlockedStatus() );
        systemRights.setDeletedStatus( systemRightsDto.isDeletedStatus() );
        systemRights.setActiveFrom( getLDTfromString( systemRightsDto.getActiveFrom() ) );
        systemRights.setActiveUntil( getLDTfromString( systemRightsDto.getActiveUntil() ) );
        systemRights.setName( systemRightsDto.getName() );
        systemRights.setDescription( systemRightsDto.getDescription() );

        return systemRights;
    }

    protected SystemRightsDto systemRightsToSystemRightsDto(SystemRights systemRights) {
        if ( systemRights == null ) {
            return null;
        }

        SystemRightsDto systemRightsDto = new SystemRightsDto();

        systemRightsDto.setId( getStringFromId( systemRights.getId() ) );
        systemRightsDto.setActiveFrom( getStringfromLDT( systemRights.getActiveFrom() ) );
        systemRightsDto.setActiveUntil( getStringfromLDT( systemRights.getActiveUntil() ) );
        systemRightsDto.setSystemProtectedStatus( systemRights.isSystemProtectedStatus() );
        systemRightsDto.setSuspendedStatus( systemRights.isSuspendedStatus() );
        systemRightsDto.setBlockedStatus( systemRights.isBlockedStatus() );
        systemRightsDto.setDeletedStatus( systemRights.isDeletedStatus() );
        systemRightsDto.setCreatedOn( getStringfromLDT( systemRights.getCreatedOn() ) );
        systemRightsDto.setModifiedOn( getStringfromLDT( systemRights.getModifiedOn() ) );
        systemRightsDto.setDeletedOn( getStringfromLDT( systemRights.getDeletedOn() ) );
        systemRightsDto.setName( systemRights.getName() );
        systemRightsDto.setDescription( systemRights.getDescription() );

        return systemRightsDto;
    }
}

Ну может дело в моем окружении (весь pom.xml не подошел):

<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<artifactId>spring-boot-starter-data-rest</artifactId>
 <artifactId>spring-boot-starter-validation</artifactId>
<artifactId>spring-boot-starter-web</artifactId>
 <artifactId>spring-boot-devtools</artifactId>
   <artifactId>postgresql</artifactId>
<artifactId>spring-boot-configuration-processor</artifactId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
<artifactId>lombok-mapstruct-binding</artifactId>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
<artifactId>spring-boot-starter-test</artifactId>


                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
11
1

Ответы 1

При использовании Mapping#expression MapStruct скопирует это как есть, без каких-либо проверок.

В этом вопросе можно найти много expression (ов). Я бы посоветовал либо выполнить сопоставление вручную, либо оставить это на усмотрение MapStruct.

Фактически вы можете удалить все @Mapping, и все должно работать правильно.

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