can't map property. Consider to declare/implement a mapping method. Can't generate mapping method from non-iterable type to iterable type

I can't seem to use mapstruct correctly

@Mapping(target = "products", source = "itemBookType")
SearchBookingResult backToTp(ItemBook itemBook);

When running this code I get the following error:

Can't map property "ProductType itemBookType" to "List<ProductOverview> products". Consider to declare/implement a mapping method: "List<ProductOverview> map(ProductType value)".

I added the following code at the bottom:

List<ProductOverview> map(ProductType value);

but still it returns me the following error:

Can't generate mapping method from non-iterable type to iterable type from java stdlib.

Itembook class:

public class ItemBook {
    private ProductType itemBookType; //ProductType class
    private Integer idref;
    private String reference;
}

ProductType class:

public enum ProductType {
    BOOK, PHONE, GAME
}

SearchBookingResult class:

public class SearchBookingResult extends BaseResponse<SearchBookingResult> {
    private String reference;
    private List<ProductOverview> products;
}

the Mapper

 @Mapper(componentModel = "spring")
    public interface ItemBookMapper {
        ItemBookTpMapper INSTANCE = Mappers.getMapper(ItemBookTpMapper.class);
        @Mapping(target = "reference", source = "idref")
        @Mapping(target = "products", source = "itemBookType")
        SearchBookingResult backToTp(ItemBook itemBook);
        List<ProductOverview> map(ProductType value);
    
    }

ProductOverView class is abstract:

public abstract class ProductOverview implements Serializable {

    private ProductType productType;

    public ProductOverview(ProductType productType) {
        this.productType = productType;
    }

    public ProductType getProductType() {
        return productType;
    }
}

map reference work but products return many error.

Upvotes: 7

Views: 35535

Answers (1)

Paul Marcelin Bejan
Paul Marcelin Bejan

Reputation: 1685

MapStruct can't generate mapping method from non-iterable type to iterable type because it's impossible to create a generic mapping.

The only solution, as suggested by the exception, is to create a custom method where you can implement your own mapping algorithm.

@Mapper(componentModel = "spring")
public interface ItemBookMapper {

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

    @Mapping(target = "reference", source = "idref")
    @Mapping(target = "products", source = "itemBookType", qualifiedByName = "mapProducts")
    SearchBookingResult backToTp(ItemBook itemBook);

    @Named("mapProducts") 
    default List<ProductOverview> mapProducts(ProductType value){
        List<ProductOverview> products = new ArrayList<>();
        
        //add your custom mapping implementation

        return products;
    }

}

Upvotes: 11

Related Questions