如何使 mapstruct 映射器 return 为 null 而不是所有字段都设置为 null 的新对象

How to make mapstruct mappers return null instead of new objects with all fields set to null

大家好!

我正在我的 Spring 应用程序中实施 Mapstruct 映射器。

有两个相关实体:UserOrder。 只是为了简化 -> User 可以有很多 Orders.

下面我将这些实体及其 DTO 模型附加在一起。

订单class:

    public class Order {
    
        ...
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "user_id")
        private User user;
        ...
    }

OrderDTO class:

    public class OrderDTO {
    
        ...
    
        private Long userId;
    
        ...
    
    }

用户class:

    public class User {
    
        ...
    
        @OneToMany(mappedBy = "user", orphanRemoval = false, fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
        private Set<Order> orders;
    
        ...
    }

UserDTO class:

    public class UserDTO {
    
        ...
    
        private Set<Long> ordersIds;
    
        ...
    }

为了澄清我的问题,让我在下面添加 OrderMapper:

CommonMapper(只是一个简单的接口,不关心泛型类型):

public interface CommonMapper<E extends AbstractEntity, D extends AbstractDto> {

    D toDto(E e);

    E fromDto(D dto);

    Set<D> toSetDto(Set<E> e);

    Set<E> fromSetDto(Set<D> d);

    List<D> toListDto(List<E> e);

    List<E> fromListDto(List<D> d);
}

OrderMapper class:

@Mapper(componentModel = "spring")
public interface OrderMapper extends CommonMapper<Order, OrderDTO> {
    OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);

    @Override
    @Mapping(source = "user.id", target = "userId")
    OrderDTO toDto(Order order);

    @Override
    @Mapping(source = "userId", target = "user.id")
    Order fromDto(OrderDTO dto);
}

好的,这是我的问题:

如果我通过以下方式传递 OrderDTO:

userID=null

我希望我的映射(通过 OrderMapper)实体将用户设置为 NULL

user = null

相反,映射器创建 new User(),所有字段都设置为 NULL

user:
field1 = null,
field2 = null, ...

你们有什么想法可以让 mapstruct mapper 在传递 null 时不初始化新对象吗?

前面描述的情况在我的应用程序中造成了巨大的问题。 我将不胜感激。

这不是一个优雅的解决方案,但它确实有效。我不确定 Mapstruct 是否已经解决了这个问题。

将此添加到 OrderMapper。

@AfterMapping
default Order afterMapping(@MappingTarget Order order) {
    if (order != null && order.getUser().getId() == null) {
        order.setUser(null);
    }
    return order;
}