提问者:小点点

使用MapStruct时存在多个构造函数时出现“发现模糊构造函数”错误


我是mapstruct的新手。我正在尝试将ItemInfo映射到Item对象,以下是我的类。

public class ItemInfo {

    private String itemOwner;
    private String itemOwnerArea;

    //getters and setters
}

以下是我打算转学的课程

public class Item {
    private UserInfo owner;
    // getters and setters.
}

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
}

我已经创建了映射器接口,如下所示

@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);
}

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

 Ambiguous constructors found for creating com.app.test.UserInfo. Either declare parameterless 
constructor or annotate the default constructor with an annotation named @Default.

你能引导我吗?

更新。

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

Property "username" has no write accessor in UserInfo for target name "owner.username".

谢啦


共3个答案

匿名用户

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

从当前错误信息

用于创建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 {
}

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

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

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

你很可能需要

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

匿名用户

Mapstruct需要一个默认的空构造函数来运行。

因此,更新UserInfo类以具有默认的空构造函数:

public class UserInfo {

    private final String username;
    private final String area;

    public UserInfo(){
        
    }

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

    public UserInfo(String info) {
        //set
    }

    // setters and getters
}

或者使用@Default注释任何构造函数,以便mapstruct可以将该构造函数用作默认构造函数。

例如:

 @Default
 public UserInfo(String info) {
    //set
 }

此外,您还必须在UserInfo中添加设置器。

匿名用户

这里是留档:https://github.com/mapstruct/mapstruct/blob/master/documentation/src/main/asciidoc/chapter-3-defining-a-mapper.asciidoc#using-constructors

使用@Default注释来标记默认构造函数。