Используя mapstruct, как отобразить объект в список объектов с помощью средств отображения компонентов Spring
Я пытаюсь сопоставить объект A со списком объекта B. У меня есть картограф, который сопоставляет объект A с объектом B.
Я пробовал несколько разных способов, например, Попытка создать список с одним объектом A, используя выражения, и qualByName, но это не работает, потому что я думаю, что при использовании выражений /qualByName вы не можете использовать пользовательские сопоставления (я мог здесь не так?)
Я также попытался вызвать маппер из метода @aftermapper, используя mappers.getMapper, чтобы получить дескриптор целевого маппера. Но я обнаружил, что пружинные бины используются в маппере, где они не заполняются. Смысл в последующем сопоставлении делает смысл в том, что я могу вызвать целевой маппер с источником и затем добавить цель в список. Поэтому я надеюсь, что есть другой способ получить дескриптор компонента mapper из моего mapper.
Все мои мапперы используют @Mapper(componentModel="spring",
Все предложения приветствуются. Ниже приведен пример кода, показывающий проблему.
С уважением, Деклан
// SPECIESTOLOGSPECY.JAVA
// From this mapper I want to call SpecyToLogDeclarationMapperApi mapper
// to map ‘species’ to ‘logdeclarations’ which is a list of logdeclaration
// you can see want I am trying to do in the aftermapping method
// where I map species to logdeclaration and then put this into a list
// unfortunately I need other mapping components (ConfigMapperFromCode & SpecyToFishDeclarationMapperApi)
// to be autowired into SpecyToLogDeclarationMapperApi and this is not happening.
// is there another way to get a handle to the spring managed
// SpecyToLogDeclarationMapperApi mapper ?
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
GeoInfoMapper.class,
SpecyToLogDeclarationMapperApi.class
})
public interface SpeciesToLogSpecy {
SpecyToLogDeclarationMapperApi MAPPER = Mappers.getMapper(SpecyToLogDeclarationMapperApi.class);
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="speciesid", qualifiedByName={"ConfigMapperFromCode", "speciesIdFromCodeAsDecimal"}, source = "species.speciesCode"),
@Mapping(target="unitweight", constant = "1"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target = "unitdefaultind", constant = "Y"),
@Mapping(target = "sectiontypeid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOG_SPECIES_SECTION_TYPE_SHEETDECLARATION))"),
@Mapping(target = "unituomid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOGSHEET_CATCHUNITS_KG))"),
@Mapping(target="catchtypeid", qualifiedByName={"ConfigMapperFromCode", "returnCatchTypeId"}, source = "species.spType"),
@Mapping(target="legalfishsizetypeid", qualifiedByName={"ConfigMapperFromCode", "legalFishSizeTypeIdFromCode"}, source = "species.fishSizeClass"),
@Mapping(target="presenttypeid", qualifiedByName={"ConfigMapperFromCode", "presentationTypeIdFromCode"}, source = "species.presentation.presentationType"),
//@Mapping(target="logdeclarations", source = "species")
}
)
Logspecy speciesToLogspecy(Species species, @Context ExtraFields extraFields);
@AfterMapping
default void afterMap(@MappingTarget Logspecy logspecy, @Context ExtraFields extraFields){
Logdeclaration logDeclaration = MAPPER.SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
logSpecy.setLogdeclarations(logdeclarations);
{
// SPECYTOLOGDECLARATIONMAPPERAPI.JAVA
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
SpecyToFishDeclarationMapperApi.class
}
)
public interface SpecyToLogDeclarationMapperApi {
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="geartypeid", qualifiedByName={"ConfigMapperFromCode", "gearIdFromCode"}, source = "species.gearType"),
@Mapping(target="fishcount", source = "species.qty"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target="packagetypeid", qualifiedByName={"ConfigMapperFromCode", "packagingTypeIdFromCode"}, source = "species.presentation.packaging"),
@Mapping(target="packagecount", source = "species.presentation.pkgunit"),
@Mapping(target="avgpackageweight", source = "species.presentation.pkgUnitWeight"),
@Mapping(target="conversionfactor", source = "species.presentation.convFactor"),
@Mapping(target="fishdeclaration", source = "species.geoInfo")
}
)
Logdeclaration SpeciesToLogDeclarations (Species species, @Context ExtraFields extraFields);
1 ответ
Проблема в том, что вы пытаетесь отобразить Species
в List<Logdeclaration>
и MapStruct не может найти такой метод отображения. Чтобы заставить его работать, вы можете добавить следующие методы к вашему SpecyToLogDeclarationMapperApi
:
default List<Logdeclaration> SpeciesToLogDeclarationsToList(Species species, @Context ExtraFields extraFields) {
if ( species == null ) {
return null;
}
Logdeclaration logDeclaration = SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
return logdeclarations;
}
Вот некоторые дополнительные вещи, которые, я думаю, вы можете сделать, чтобы улучшить свой код и использовать MapStruct "более правильно":
- Вам нужно будет удалить использование
Mappers#getMapper(Class)
когда компонентная модель не являетсяdefault
- Если вы не хотите использовать FQN в своих выражениях, вы можете использовать
Mapper#imports
и MapStruct будет импортировать их в реализации. - Когда у вас есть один параметр источника, вам не нужно использовать его имя в отображении
например
@Mapping(target="fishcount", source = "species.qty")
может быть
@Mapping(target="fishcount", source = "qty")