使用 MapStruct 时有多个构造函数时出现“发现二义性构造函数”错误

Cha*_*ake 4 java mapstruct

我是 mapstruct 的新手。我正在尝试映射ItemInfoItem对象,以下是我的类。

public class ItemInfo {

    private String itemOwner;
    private String itemOwnerArea;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

以下是我打算转换为的课程

public class Item {
    private UserInfo owner;
    // getters and setters.
}
Run Code Online (Sandbox Code Playgroud)

UserInfo 类(注意它有两个构造函数)

public class UserInfo {

    private final String username;
    private final String area;

    public UserInfo(String username, String area){
        //set 
    }

    public UserInfo(String info) {
        //set
    }

    // getters only
}
Run Code Online (Sandbox Code Playgroud)

我已经创建了如下的映射器界面

@Mapper
public interface ItemMapper {
    ItemMapper INSTANCE = Mappers.getMapper(ItemMapper.class);

    @Mapping(source = "itemOwner", target = "owner.username")
    @Mapping(source = "itemOwnerArea", target = "owner.area")
    Item mapItemInfoToItem(ItemInfo itemInfo);
}
Run Code Online (Sandbox Code Playgroud)

当我构建这个时,我收到以下错误

 Ambiguous constructors found for creating com.app.test.UserInfo. Either declare parameterless 
constructor or annotate the default constructor with an annotation named @Default.
Run Code Online (Sandbox Code Playgroud)

你能指导我吗?

更新。

正如@AnishB 所提到的,我添加了一个默认构造函数,但出现了不同的错误

Property "username" has no write accessor in UserInfo for target name "owner.username".
Run Code Online (Sandbox Code Playgroud)

谢谢

Fil*_*lip 5

我们正在努力改进这个地方的错误信息。

从当前的错误信息

发现用于创建com.app.test.UserInfo. 声明无参数构造函数或使用名为@Default.

您有 2 个选择:

  • 创建一个空的构造函数,MapStruct 将使用它。然而,这不是必需的,我强烈建议不要使用它。
  • 创建您自己的@Default注释并注释 MapStruct 应使用的默认构造函数。我强烈推荐这种方法。

MapStruct 没有传送这个注解,因为它专注于 bean 映射并且不想用来自 MapStruct 的注解污染实体代码。因此它可以使用Default任何包中的任何注释。

例如

package foo.support.mapstruct;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.CLASS)
public @interface Default {
}
Run Code Online (Sandbox Code Playgroud)

你已经这样做了,下一条错误消息:

属性“username”在 UserInfo 中没有针对目标名称“owner.username”的写访问器。

有没有说用户名没有写访问器,因为很可能你已经注释了单参数构造函数。如果你这样做,然后MapStruct只知道的area,而不是有关username。该错误的另一个选择是您添加了一个空的无参数构造函数并且没有设置器。

你很可能需要

@Default
public UserInfo(String username, String area){
    //set 
}
Run Code Online (Sandbox Code Playgroud)