我使用的是Spring Data Jdbc,我有两个与引用id相关的聚合。
public class ResourceEntity {
@Id
@With
private final UUID id;
private String institutionId;
private String version;
private Long resourceTypeId;
public class ResourceTypeEntity {
@Id @With
private final Long id;
private String name;
我想将其映射为GRPC消息,该消息将被翻译为
public class Resource {
private String institutionId;
private String version;
private String name; <-- This should be mapped after lookup the ResourceTypeEntity byId
}
我创建了一个类似的ResourceMapper
@Mapper(unmappedTargetPolicy = org.mapstruct.ReportingPolicy.IGNORE,
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface ResourceMapper {
ResourceMapper mapper = Mappers.getMapper(ResourceMapper.class);
@Mapping(target = "name", source = "resourceTypeId", ????
Resource toResource(ResourceEntity resourceEntity);
List<Resource> toResources(List<ResourceEntity> resourceEntities);
本质上,我想使用resourceTypeRepository.findById(resourceTypeId(来获取ResourceTypeEntity并映射名称。
如何做到这一点?
感谢
您没有机会通过接口实现这一点,只要您需要自动连接存储库以获取对象及其名称以进行进一步映射。但是,您可以使用abstract class
,它与MapStruct类生成(包括Spring组件模型(完全兼容。
@Mapper(
componentModel = "spring",
unmappedTargetPolicy = org.mapstruct.ReportingPolicy.IGNORE,
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public abstract static class ResourceMapper {
@Autowired
private ResourceTypeRepository repository;
public abstract Resource toResource(ResourceEntity resourceEntity);
public abstract List<Resource> toResources(List<ResourceEntity> resourceEntities);
@AfterMapping
public void afterMapping(@MappingTarget Resource resource, ResourceEntity entity) {
long id = resourceEntity.getResourceTypeId();
// Call the repository to fetch ResourceTypeEntity by resourceTypeId
// The method results in Optional<ResourceTypeEntity> so you might want to
// ... throw an exception or use a default value if no entity by id is found
String name = repository.findById(id)
.map(ResourceTypeEntity::getName)
.orElse(null);
resource.setName(name);
}
}
@Autowire
private ResourceMapper resourceMapper;
void foo() {
ResourceEntity resourceEntity = ...
Resource resource = resourceMapper.toResource(resourceEntity);
}
请记住,这是一个服务,而不仅仅是一个实体dto映射器——只要其中的逻辑不是琐碎的,并且依赖于数据库连接和数据。我宁愿创建一个@Service
,它使用interface ResourceMapper
,方法不提取数据(而是提取服务层(,而是通过@Context
:传递name
Resource toResource(ResourceEntity entity, @Context String name);
@AfterMapping
void toResourceAfterMapping(
@MappingTarget Resource resource, ResourceEntity entity, @Context String name
) {
resource.setName(name);
}