MapStruct не преобразует идентификаторы List<Integer> в List<Product>

У меня есть объект Order, который выглядит так

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;
    @Enumerated(EnumType.STRING)
    @Column(name = "order_status")
    private OrderStatus status;
    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.DETACH, CascadeType.REFRESH})
    @JoinTable(name = "order_product"
            ,joinColumns = @JoinColumn(name = "order_id")
            ,inverseJoinColumns = @JoinColumn(name = "product_id"))
    private List<Product> productList;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    @Column(name = "ordered_at")
    private LocalDateTime orderTime;

    @OneToOne
    @JoinTable(name = "order_payment"
            ,joinColumns = @JoinColumn(name = "order_id",referencedColumnName = "id")
            ,inverseJoinColumns = @JoinColumn(name = "payment_id", referencedColumnName = "id"))
    private Payment payment;

    @ManyToOne
    @JoinColumn(name = "shop_id")
    private Shop shop;
    ... 
    contsructor getter and setters
}

ЗаказатьPostDto

public class OrderPostDto {
private int id;
private OrderStatus status;
private int userId;
private LocalDateTime orderTime;
private List<Integer> productIds;
private int shopId;
...
constructor getter and setters
}

MapStruct OrderMapper

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = {ProductService.class, ShopService.class, UserService.class})
    public interface OrderMapper {
        OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);
    
        OrderDto orderToDto(Order order);
    
        @Mapping(source = "userId", target = "user")
        @Mapping(source = "productIds", target = "productList")
        @Mapping(source = "shopId", target = "shop")
        Order dtoToOrder(OrderPostDto dto);
    }

Как вы можете видеть, OrderDto принимает идентификаторы продуктов как целые числа, и OrderMapper должен сопоставлять их с объектом из таблицы продуктов базы данных. Но он генерирует такой код:

protected List<Product> integerListToProductList(List<Integer> list) {
        if ( list == null ) {
            return null;
        }

        List<Product> list1 = productService.getAllProducts();
        for ( Integer integer : list ) {
            list1.add( productService.getProductById( integer.intValue() ) );
        }

        return list1;
    }

Но по какой-то причине он создает list1, который содержит все элементы из базы данных List<Product> list1 = productService.getAllProducts(); Но мне нужно добиться такого поведения List<Product> list1 = new ArrayList<>(list.size()); Как мне заставить его генерироваться таким образом?

Вы пытались объявить абстрактный @IterableMapping List<Product> map(List<Integer>) в своем картографе?

Luca Basso Ricci 06.10.2022 08:00
0
1
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я решил свою проблему, я просто определил картограф как абстрактный класс с реализацией этого конкретного метода. Так это будет выглядеть так:

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = {ProductService.class, ShopService.class, UserService.class})
public abstract class OrderMapper {
    @Autowired
    protected ProductService productService;

    public abstract OrderDto orderToDto(Order order);

    @Mapping(source = "userId", target = "user")
    @Mapping(source = "productIds", target = "productList")
    @Mapping(source = "shopId", target = "shop")
    public abstract Order dtoToOrder(OrderPostDto dto);

    public List<Product> integerListToProductList(List<Integer> list) {
        if ( list == null ) {
            return null;
        }

        List<Product> list1 = new ArrayList<>(list.size());
        for ( Integer integer : list ) {
            list1.add( productService.getProductById( integer.intValue() ) );
        }

        return list1;
    }
}

Другие вопросы по теме