首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Mapstruct中使用Vavr列表:没有为返回类型io.vavr.collection.List注册实现类型。

在Mapstruct中使用Vavr列表:没有为返回类型io.vavr.collection.List注册实现类型。
EN

Stack Overflow用户
提问于 2021-07-17 00:03:13
回答 1查看 315关注 0票数 0

我试图在一个具有Vavr列表的对象上使用Mapstruct。

但是我得到了错误java: No implementation type is registered for return type io.vavr.collection.List,但是在java.util.List上工作得很好。

几年前,我看到了关于"Page“数据类型Mapstruct return type的另一个问题,它有类似的错误,但我没有看到任何更新。

没有解决办法吗?在调用对象上的mapstruct mapper时,我可以将vavr列表更改为Java列表,反之亦然,但是如果对象有具有vavr列表的子对象,那么我不确定可以做什么,因为在mapstruct mapper文件中,我什么都不能做。

我正在使用最新的mapstruct版本:

代码语言:javascript
复制
      <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok-mapstruct-binding</artifactId>
            <version>0.2.0</version>
        </dependency>

ParentObject:

代码语言:javascript
复制
import io.vavr.collection.List;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ParentObject {
    private String parentField;

    private List<ParentInnerObject> parentInnerObjectList;

ParentInnerObject:

代码语言:javascript
复制
@Data
@Builder
public class ParentInnerObject {
    private String parentInnerField;

ChildObject:

代码语言:javascript
复制
import io.vavr.collection.List;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ChildObject {
    private String childField;

    private List<ChildInnerObject> childInnerObjectList;

ChildInnerObject:

代码语言:javascript
复制
@Data
@Builder
public class ChildInnerObject {
    private String childInnerField;

示例映射器将ParentObject映射到ChildObject:

代码语言:javascript
复制
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN)
public abstract class TestMapper {

    @Mapping(source = "parentField", target = "childField")
    @Mapping(source = "parentInnerObjectList", target = "childInnerObjectList")
    public abstract ChildObject toChildObject(final ParentObject parentObject);

    public abstract List<ChildInnerObject> toChildObjects(
            final List<ParentInnerObject> parentInnerObjectList);

    @Mapping(source = "parentInnerField", target = "childInnerField")
    public abstract ChildInnerObject toChildInnerObject(final ParentInnerObject parentInnerObject);

测试类以测试映射程序代码:

代码语言:javascript
复制
import io.vavr.collection.List;

@ExtendWith(MockitoExtension.class)
class TestMapperTest {
  //https://stackoverflow.com/questions/34067956/how-to-use-injectmocks-along-with-autowired-annotation-in-junit
  @Autowired
  @InjectMocks
  private TestMapperImpl testMapper;

  @Test
  @DisplayName("Check if the value is returned correctly")
  void testMapperCode(){
    ParentObject pa = ParentObject.builder()
            .parentField("parent field")
            .parentInnerObjectList(List.of(ParentInnerObject.builder()
                    .parentInnerField("parent inner field")
                    .build()))
            .build();
    /*ParentObject pa = ParentObject.builder()
            .parentField("parent field")
            .parentInnerObjectList(Collections.singletonList(ParentInnerObject.builder()
                    .parentInnerField("parent inner field")
                    .build()))
            .build();*/
    ChildObject childObject = testMapper.toChildObject(pa);
    System.out.println(childObject);
  }

}

编辑:-现在使用自定义映射程序,直到mapstruct中支持vavr列表。

代码语言:javascript
复制
import io.vavr.collection.Iterator;
import io.vavr.collection.List;

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN)
public abstract class TestMapper {
    @Mapping(source = "parentField", target = "childField")
    //@Mapping(source = "parentInnerObjectList", target = "childInnerObjectList") //This does not work as Mapstruct does not support Vavr list yet
    @Mapping(target = "childInnerObjectList", expression = "java(vavrListSetter(parentObject.parentInnerObjectList))") //custom mapper
    public abstract ChildObject toChildObject(final ParentObject parentObject);

    @Mapping(source = "parentInnerField", target = "childInnerField")
    public abstract ChildInnerObject toChildInnerObject(final ParentInnerObject parentInnerObject);

    public List<ChildInnerObject> vavrListSetter(final List<ParentInnerObject> parentInnerObjectList) {
        if (parentInnerObjectList == null) {
            return null;
        }
        return Iterator.ofAll(parentInnerObjectList)
                .map(this::toChildInnerObject)
                .collect(List.collector());
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-17 07:41:31

Spring数据页数据类型与Vavr列表不同。需要将Page数据类型视为bean而不是可迭代的,这将在即将发布的1.5版中得到修正。

至于Vavr列表,MapStruct现在不支持使用它。您可以提出一个特性请求,这样我们就可以讨论潜在的解决方案。

目前,唯一的方法是编写自定义映射方法,以便在这些列表之间进行映射。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68416376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档