如何使 mapstruct 映射器 return 为 null 而不是所有字段都设置为 null 的新对象
How to make mapstruct mappers return null instead of new objects with all fields set to null
大家好!
我正在我的 Spring 应用程序中实施 Mapstruct 映射器。
有两个相关实体:User
和 Order
。
只是为了简化 -> 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;
}
大家好!
我正在我的 Spring 应用程序中实施 Mapstruct 映射器。
有两个相关实体:User
和 Order
。
只是为了简化 -> 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;
}