【问题标题】:MapStruct / mapping interface field / javaMapStruct/映射接口字段/java
【发布时间】:2021-10-09 22:11:24
【问题描述】:

你好!我一直在尝试使用 MapStruct 将 BookDTO.java 映射到 Book.java,但我遇到了问题

这是我的 DTO:

BookDTO.java:

@Data
@Document
public class BookDTO {

    @Id
    private UUID id;
    private BookSpecificationsDTO specifications;

}

BookSpecificationsDTO 接口:

public interface BookSpecificationsDTO {
    BookSpecificationsTypeDTO type = null;

    default BookSpecificationsTypeDTO getType() {
        return type;
    }
}

BookSpecificationsTypeDTO:

public enum BookSpecificationsTypeDTO{

    CLASSIC,
    PHANTASY
}

ClassicBookSpecificationDTO:

@Data
public class ClassicBookSpecificationDTO implements BookSpecificationsDTO {
    private BookSpecificationsTypeDTO type = BookSpecificationsTypeDTO.CLASSIC;
    private String genre;
    private int length;
}

PhantasyBookSpecificationDTO:

@Data
    public class PhantasyBookSpecificationDTO implements BookSpecificationsDTO {
        private BookSpecificationsTypeDTO type = BookSpecificationsTypeDTO.PHANTASY;
        private String genre;
   }

这是我的模型,在我的例子中与 DTO 的模型相同:

Book.java:

@Data
@Document
public class Book {

    @Id
    private UUID id;
    private BookSpecifications specifications;

}

BookSpecifications 接口:

public interface BookSpecifications {
    BookSpecificationsType type = null;

    default BookSpecificationsType getType() {
        return type;
    }
}

BookSpecificationsType:

public enum BookSpecificationsType{

    CLASSIC,
    PHANTASY
}

经典书籍规格:

@Data
public class ClassicBookSpecification implements BookSpecifications {
    private BookSpecificationsType type = BookSpecificationsType.CLASSIC;
    private String genre;
    private int length;
}

PhantasyBook规范:

@Data
    public class PhantasyBookSpecification implements BookSpecifications {
        private BookSpecificationsType type = BookSpecificationsType.PHANTASY;
        private String genre;
   }

我想将我的 BookDTO.java 映射到我的 Book.java 模型。这是映射器类:

@Mapper(componentModel = "spring", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface BookMapper {
        
    @Mapping(target = "id", expression = "java(java.util.UUID.randomUUID())")
    Book toBook(BookDTO bookDTO);

}

这是我得到的错误:

java: The return type BookSpecificationsDTO is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.

java: Can't map property "BookSpecificationsDTO specifications" to "BookSpecifications specifications". Consider to declare/implement a mapping method: "BookSpecifications map(BookSpecificationsDTO value)".

所以,我的问题是我能以某种方式完成这项工作吗?如果其中一个字段是接口,是否可以在这种情况下将 BookDTO.java 映射到 Book.java?提前致谢!

【问题讨论】:

  • 你知道接口中的字段隐含static,对吗?
  • 看起来您正在尝试编写一个 mixin,而 Java 不支持该功能。 (Groovy trait 可以做到这一点,但如果你想在 Java 中做到这一点,你需要一个抽象基类。)

标签: java spring interface mapping mapstruct


【解决方案1】:

当目标类型是接口或抽象类时,必须是以下之一:

  • 使用@ObjectFactory 注释的方法将创建目标对象
  • 使用@BeanMapping(resultType = XXX.class) 的映射方法将定义结果类型

在您的情况下,由于您的接口没有设置器,因此问题稍微复杂一些。因此,您需要 Support for Type-Refinement mapping (or Downcast Mapping) 之类的东西,这目前是一个功能请求,还不能开箱即用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2017-12-11
    • 2018-07-29
    • 1970-01-01
    • 2016-04-19
    • 2020-04-24
    相关资源
    最近更新 更多