下面是一个非常简化的汽车共享模型,其中一个
Car
可能被多个User
使用。我需要将服务对象转换为 DTO 对象,反之亦然:
@Data
public class Car {
private String brand;
private String model;
private List<CarUser> users = new ArrayList<>();
public void linkUser(CarUser user) {
this.users.add(user);
user.setCar(this);
}
}
@Data
public class CarUser {
private String name;
private Car car;
}
@Data
public class CarDTO {
private String brand;
private String model;
private List<CarUserDTO> users = new ArrayList<>();
public void linkUser(CarUserDTO user) {
this.users.add(user);
user.setCar(this);
}
}
@Data
public class CarUserDTO {
private String name;
private CarDTO car;
}
@Mapper
public interface UserConverter {
CarUser convert(final CarUserDTO user);
CarUserDTO convert(final CarUser user);
}
@Mapper(uses = UserConverter.class)
public interface CarConverter {
Car convert(final CarDTO car);
CarDTO convert(final Car car);
}
方法
linkUser
创建双向链接,即将给定 User
关联到当前 Car
,并将当前 Car
关联到给定 User
。上面代码片段中 Mapper
的问题在于,类 car
/User
中的 UserDTO
属性永远不会被设置,因为转换器当然不会调用 linkUser
。有什么办法可以设置该属性吗?这里棘手的部分是要设置的 Car
实际上是正在转换的实例。任何帮助将非常感激:-)
您可以简单地在 @AfterMapping
中定义一个
CarConverter
方法。重点是克隆已转换用户的列表并将 users
属性设置为空列表,因为调用 linkUser
方法时将重新填充用户列表。
@Mapper(uses = UserConverter.class)
public interface CarConverter {
Car convert(final CarDTO car);
CarDTO convert(final Car car);
@AfterMapping
default void linkUsersDTO(Car source, @MappingTarget CarDTO target) {
List<CarUserDTO> users = new ArrayList<>(target.getUsers());
target.setUsers(new ArrayList<>());
users.forEach(target::linkUser);
}
@AfterMapping
default void linkUsers(CarDTO source, @MappingTarget Car target) {
List<CarUser> users = new ArrayList<>(target.getUsers());
target.setUsers(new ArrayList<>());
users.forEach(target::linkUser);
}
}
此外,由于用户的
car
属性是在 @AfterMapping
方法中设置的,因此无需在 UserConverter::convert
中映射它。
@Mapper
public interface UserConverter {
@Mapping(target= "car",ignore = true)
CarUser convert(final CarUserDTO user);
@Mapping(target= "car",ignore = true)
CarUserDTO convert(final CarUser user);
}
如果不忽略,则会抛出
StackOverflowError
异常,因为 UserConverter
生成的方法形成循环依赖。