我有2个实体,通过一对一依赖关系进行连接。
用户:
public class User {
@OneToOne(cascade = [CascadeType.ALL], fetch = FetchType.EAGER, mappedBy = "user")
private UserParams params;
...
}
UserParams:
public class UserParams {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
...
}
我用ModelMapper对其进行了转换:
@Bean
public ModelMapper modelMapper() {
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT)
.setFieldMatchingEnabled(true)
.setSkipNullEnabled(true)
.setPropertyCondition(Conditions.isNotNull())
.setFieldAccessLevel(PRIVATE);
return mapper;
}
我将解释mapper的工作原理。我从UserParams映射中排除“用户”字段,并将其单独映射。这样,我只接收UserParams的'user'字段的ID和User的完整dto'params'。
//exclude from mapping
@PostConstruct
public void init() {
mapper.createTypeMap(UserParams.class, UserParamsDto.class)
.addMappings(m -> m.skip(UserParamsDto::setUser)).setPostConverter(toDtoConverter());
mapper.createTypeMap(UserParamsDto.class, UserParams.class)
.addMappings(m -> m.skip(UserParams::setUser)).setPostConverter(toEntityConverter());
}
//map separately
@Override
protected void mapSpecificFields(UserParams source, UserParamsDto destination) {
whenNotNull(source.getUser(), u -> destination.setUser(u.getId()));
}
@Override
protected void mapSpecificFields(UserParamsDto source, UserParams destination) {
whenNotNull(source.getUser(), u -> destination.setUser(userRepository.findById(u).orElse(null)));
}
后转换器实现转换:
protected Converter<E, D> toDtoConverter() {
return context -> {
E source = context.getSource();
D destination = context.getDestination();
mapSpecificFields(source, destination);
return context.getDestination();
};
}
protected Converter<D, E> toEntityConverter() {
return context -> {
D source = context.getSource();
E destination = context.getDestination();
mapSpecificFields(source, destination);
return context.getDestination();
};
}
然后,当我调用UserParams(通过/ params?id = 1)时,我使用已填充的用户重新接收JSON:
{
"id": 5,
"created": "2019-06-13T20:07:52.221",
"updated": null,
"user": 1,
"height": 180,
"weight": 75,
"gender": null,
"birthDate": null
}
但是当我打电话给用户时,字段参数会转换为dto(字段用户除外):
{
"id": 1,
"created": "2019-06-13T19:50:16",
"updated": null,
"params": {
"id": 2,
"created": "2019-06-13T19:50:22",
"updated": null,
"user": null, //null
"height": 180,
"weight": 75,
"gender": null,
"birthDate": null
}
}
据我了解,当映射用户时,映射器不为嵌套对象调用postConverter,我使用断点进行了检查。为什么?该怎么办? 项目here。