TL;DR
我想以从 AbstractParent 映射到 AbstractParentDTO 的方式使用 modelMapper,然后在 ModelMapper-Config 中调用每个子类的特定映射器,然后跳过其余的(抽象类)映射。
这怎么可能?这是正确的方法吗?是否存在设计缺陷?
我拥有的:
父实体:
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type")
public abstract class Parent {
//some more fields
}
一个子实体:
//Basic Lombok Annotations
@DiscriminatorValue("child_a")
public class ChildA extends Parent {
//some more fields
}
另一个子实体:
@DiscriminatorValue("child_b")
public class ChildB extends Parent {
//some more fields
}
然后我有父 DTO 类:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(value = ChildA.class, name = "child_a"),
@JsonSubTypes.Type(value = ChildB.class, name = "child_b"),
public abstract class ParentDTO {
//some more fields
}
一孩 DTO:
public class ClassADTO extends ParentDTO {
//some more fields
}
和另一个 DTO:
public class ClassBDTO extends ParentDTO {
//some more fields
}
就我而言,我将从控制器获取 DTO,并在将它们提供给服务时将它们映射到实体。我必须在 5-6 个端点中做同样的事情。
端点大致如下所示:
@PreAuthorize(CAN_WRITE)
@PutMapping("/{id}")
public ResponseEntity<ParentDTO> update(
@PathVariable("id") UUID id,
@RequestBody @Valid ParentDTO parentDTO) {
Parent parent = parentService.update(id, parentDTO);
if (parentDTO instanceof ChildADTO) {
return ResponseEntity.ok(modelMapper.map(parent, ChildADTO.class));
} else if (parentDTO instanceof ChildBDTO) {
return ResponseEntity.ok(modelMapper.map(parent, ChildBDTO.class));
}
throw new BadRequestException("The Parent is not Valid");
}
只是我还有几个孩子让事情变得更加笨重。
我想要的是:
我不想多次检查 DTO(或实体)是什么实例,而是只想写:
modelmapper.map(parent, ParentDTO.class)
并在我的 ModelMapper 配置中检查一次“...的实例”。
我尝试过的:
我已经为 ModelMapper 配置中定义的每个可能的方向和映射情况提供了不同的转换器(因为它们无论如何都需要更复杂的映射)。
我尝试通过为父类再编写一个转换器并将其设置为 ModelMapper PreConverter 来解决我的问题:
//from Entity to DTO
Converter<Parent, ParentDTO> parentParentDTOConverter = mappingContext -> {
Parent source = mappingContext.getSource();
ParentDTO dest = mappingContext.getDestination();
if (source instanceof CHildA) {
return modelMapper.map(dest, ChildADTO.class);
} else if (source instanceof ChildB) {
return modelMapper.map(dest, ChildBDTO.class);
}
return null;
};
and:
modelMapper.createTypeMap(Parent.class, ParentDTO.class)
.setPreConverter(parentParentDTOConverter);
但我总是遇到相同的 MappingError:
1) 实例化目标实例失败
com.myexample.data.dto.ParentDTO。确保这件事
com.myexample.data.dto.ParentDTOO 有一个非私有无参数
构造函数。
我得到(我猜),我无法构造抽象类的对象。但这不是我正在尝试的,不是吗?
我猜想 modelMapper 在完成我的 PreConverter 后仍在进行其余的映射。我也尝试使用 .setConverter 设置它,但总是得到相同的结果。
任何帮助和提示表示赞赏。