Mapstruct uses not working, how to make mapstruct "uses" use other mapper for inner fields

huangapple go评论85阅读模式
英文:

Mapstruct uses not working, how to make mapstruct "uses" use other mapper for inner fields

问题

Mapstruct的"uses"选项不起作用,它将所有实体映射到一个映射器中,而不是为不同的实体使用不同的映射器。我有一个pom文件如下所示:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${compiler.version}</version>
    <configuration>
        <source>17</source>
        <target>17</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>0.2.0</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

RoomMapper接口如下:

@Mapper(uses = {ParticipantMapper.class})
public interface RoomMapper {

    RoomMapper INSTANCE = Mappers.getMapper(RoomMapper.class);

    @Mapping(target = "participant", source = "participant")
    RoomFullDto entityToData(RoomEntity entity);

    @Mapping(target = "participant", source = "participant")
    RoomEntity dataToEntity(RoomFullDto entity);

    @Named("EntityToShortData")
    RoomShortDto entityToShortData(RoomEntity entity);

    @Named("DataToEntity")
    RoomEntity shortDataToEntity(RoomShortDto entity);
}

ParticipantMapper接口如下:

@Mapper
public interface ParticipantMapper {

    ParticipantMapper INSTANCE = Mappers.getMapper(ParticipantMapper.class);

    @Named("DataToEntity")
    @Mapping(target = "room.id", source = "roomId")
    @Mapping(target = "user.id", source = "userId")
    @Mapping(target = "nicknameInRoom", source = "username")
    ParticipantEntity dtoToEntity(ParticipantDto participantDto);

    @Named("EntityToData")
    @Mapping(target = "roomId", source = "room.id")
    @Mapping(target = "userId", source = "user.id")
    @Mapping(target = "username", source = "nicknameInRoom")
    ParticipantDto entityToDto(ParticipantEntity participantDto);
}

在RoomMapperImpl中,Mapstruct生成的映射器未使用ParticipantMapper,因此您无法配置如何映射字段,并且忽略了某些字段。解决这个问题,您可以尝试以下几点:

  1. 确保在RoomMapper接口上使用了@Mapper(uses = {ParticipantMapper.class})

  2. 确保RoomMapperImpl类已由Mapstruct生成。您可以检查生成的源代码,看看是否有RoomMapperImpl类。

  3. 确保您的IDE或构建工具已正确配置,以确保Mapstruct的注解处理器已启用。

  4. 尝试清理和重新构建项目,以确保所有依赖项和生成的代码都处于最新状态。

如果您仍然遇到问题,可能需要检查您的依赖项版本和配置是否正确,并确保所有的注解都按照预期工作。如果问题仍然存在,请提供更多详细信息以获取更多帮助。

英文:

Mapstruct "uses" not working, it maps all entities in one mapper, instead of using different mappers for different entities
I have pom

`&lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
            &lt;version&gt;${compiler.version}&lt;/version&gt;
            &lt;configuration&gt;
                &lt;source&gt;17&lt;/source&gt;
                &lt;target&gt;17&lt;/target&gt;
                &lt;annotationProcessorPaths&gt;
                    &lt;path&gt;
                        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
                        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
                        &lt;version&gt;${lombok.version}&lt;/version&gt;
                    &lt;/path&gt;
                    &lt;path&gt;
                        &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
                        &lt;artifactId&gt;mapstruct-processor&lt;/artifactId&gt;
                        &lt;version&gt;${mapstruct.version}&lt;/version&gt;
                    &lt;/path&gt;
                    &lt;path&gt;
                        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
                        &lt;artifactId&gt;lombok-mapstruct-binding&lt;/artifactId&gt;
                        &lt;version&gt;0.2.0&lt;/version&gt;
                    &lt;/path&gt;
                &lt;/annotationProcessorPaths&gt;
            &lt;/configuration&gt;
        &lt;/plugin&gt;`
@Mapper(uses = {ParticipantMapper.class})
public interface RoomMapper {

    RoomMapper INSTANCE = Mappers.getMapper(RoomMapper.class);

    @Mapping(target = &quot;participant&quot;, source = &quot;participant&quot;)
    RoomFullDto entityToData(RoomEntity entity);

    @Mapping(target = &quot;participant&quot;, source = &quot;participant&quot;)
    RoomEntity dataToEntity(RoomFullDto entity);

    @Named(&quot;EntityToShortData&quot;)
    RoomShortDto entityToShortData(RoomEntity entity);

    @Named(&quot;DataToEntity&quot;)
    RoomEntity shortDataToEntity(RoomShortDto entity);
}

and

@Mapper
public interface ParticipantMapper {


    ParticipantMapper INSTANCE = Mappers.getMapper(ParticipantMapper.class);

    @Named(&quot;DataToEntity&quot;)
    @Mapping(target = &quot;room.id&quot;, source = &quot;roomId&quot;)
    @Mapping(target = &quot;user.id&quot;, source = &quot;userId&quot;)
    @Mapping(target = &quot;nicknameInRoom&quot;, source = &quot;username&quot;)
    ParticipantEntity dtoToEntity (ParticipantDto participantDto);

    @Named(&quot;EntityToData&quot;)
    @Mapping(target = &quot;roomId&quot;, source = &quot;room.id&quot;)
    @Mapping(target = &quot;userId&quot;, source = &quot;user.id&quot;)
    @Mapping(target = &quot;username&quot;, source = &quot;nicknameInRoom&quot;)
    ParticipantDto entityToDto (ParticipantEntity participantDto);
}

in RoomMapperImpl mapstruct generate without using ParticipantMapper, so i cant't configure how to map fields and it ignores some fields

public RoomFullDto entityToData(RoomEntity entity) {
        if ( entity == null ) {
            return null;
        }

        RoomFullDto roomFullDto = new RoomFullDto();

        roomFullDto.setParticipant( participantEntitySetToParticipantDtoList( entity.getParticipant() ) );
        roomFullDto.setId( entity.getId() );
        roomFullDto.setName( entity.getName() );

        return roomFullDto;
    }

protected List&lt;ParticipantDto&gt; participantEntitySetToParticipantDtoList(Set&lt;ParticipantEntity&gt; set) {
        if ( set == null ) {
            return null;
        }

        List&lt;ParticipantDto&gt; list = new ArrayList&lt;ParticipantDto&gt;( set.size() );
        for ( ParticipantEntity participantEntity : set ) {
            list.add( participantEntityToParticipantDto( participantEntity ) );
        }

        return list;
    }

ParticipantDto participantEntityToParticipantDto(ParticipantEntity participantEntity) {
        if ( participantEntity == null ) {
            return null;
        }

        ParticipantDto participantDto = new ParticipantDto();

        participantDto.setId( participantEntity.getId() );
        participantDto.setIsBanned( participantEntity.getIsBanned() );
        if ( participantEntity.getRole() != null ) {
            participantDto.setRole( participantEntity.getRole().name() );
        }

        return participantDto;
    }

I tried to configure different versions of dependencies and annotationProcessors, it dont works

答案1

得分: 0

以下是翻译好的部分:

  • RoomFullDto#participant 字段类型是 java.util.List&lt;ParticipantDto&gt;(而不是 ParticipantDto
  • ParticipantEntity#participant 字段类型是 java.util.Set&lt;ParticipantEntity&gt;(而不是 ParticipantEntity
  • 我们需要声明两个不同类型之间的映射过程:Set&lt;ParticipantEntity&gt;List&lt;ParticipantDto&gt; 的转换
    1. Set&lt;ParticipantEntity&gt;List&lt;ParticipantDto&gt; 的转换
    1. List&lt;ParticipantDto&gt;Set&lt;ParticipantEntity&gt; 的转换
  • 请尝试在 ParticipantMapper.java 中添加两个额外的方法:
  • 创建一个名为 ParticipantMapper#mapToList 的新方法
  • @Mapper
  • public interface ParticipantMapper {
  • ParticipantMapper INSTANCE = Mappers.getMapper(ParticipantMapper.class);
  • @Named(&quot;DataToEntity&quot;)
  • @Mapping(target = &quot;room.id&quot;, source = &quot;roomId&quot;)
  • @Mapping(target = &quot;user.id&quot;, source = &quot;userId&quot;)
  • @Mapping(target = &quot;nicknameInRoom&quot;, source = &quot;username&quot;)
  • ParticipantEntity dtoToEntity (ParticipantDto participantDto);
  • @Named(&quot;EntityToData&quot;)
  • @Mapping(target = &quot;roomId&quot;, source = &quot;room.id&quot;)
  • @Mapping(target = &quot;userId&quot;, source = &quot;user.id&quot;)
  • @Mapping(target = &quot;username&quot;, source = &quot;nicknameInRoom&quot;)
  • ParticipantDto entityToDto (ParticipantEntity participantDto);
  • //+ 2 additional mapping methods without any annota
  • List&lt;ParticipantDto&gt; mapToDtoList(Set&lt;ParticipantEntity&gt; set);
  • Set&lt;ParticipantEntity&gt; mapToEntitySet(List&lt;ParticipantDto&gt; list);
  • MapStruct 文档:6. 映射集合
英文:

The RoomFullDto#participant field type is java.util.List&lt;ParticipantDto&gt; (not ParticipantDto)

The ParticipantEntity#participant field type is java.util.Set&lt;ParticipantEntity&gt; (not ParticipantEntity)

We need to declare the mapping process between two different types: Set&lt;ParticipantEntity&gt; and List&lt;ParticipantDto&gt;

  1. Set&lt;ParticipantEntity&gt; -> List&lt;ParticipantDto&gt; transformation
  2. List&lt;ParticipantDto&gt; -> Set&lt;ParticipantEntity&gt; transformation

Please try to add 2 more methods for ParticipantMapper.java:

Create a new method ParticipantMapper#mapToList:

@Mapper
public interface ParticipantMapper {
  

    ParticipantMapper INSTANCE = Mappers.getMapper(ParticipantMapper.class);

    @Named(&quot;DataToEntity&quot;)
    @Mapping(target = &quot;room.id&quot;, source = &quot;roomId&quot;)
    @Mapping(target = &quot;user.id&quot;, source = &quot;userId&quot;)
    @Mapping(target = &quot;nicknameInRoom&quot;, source = &quot;username&quot;)
    ParticipantEntity dtoToEntity (ParticipantDto participantDto);

    @Named(&quot;EntityToData&quot;)
    @Mapping(target = &quot;roomId&quot;, source = &quot;room.id&quot;)
    @Mapping(target = &quot;userId&quot;, source = &quot;user.id&quot;)
    @Mapping(target = &quot;username&quot;, source = &quot;nicknameInRoom&quot;)
    ParticipantDto entityToDto (ParticipantEntity participantDto);
  

    //+ 2 additional mapping methods without any annota
    List&lt;ParticipantDto&gt; mapToDtoList(Set&lt;ParticipantEntity&gt; set);

    Set&lt;ParticipantEntity&gt; mapToEntitySet(List&lt;ParticipantDto&gt; list);
}

MapStruct Documentation: 6. Mapping collections

huangapple
  • 本文由 发表于 2023年7月23日 23:01:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76748919.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定