MapStruct не удалось создать сопоставитель для сгенерированных классов XJC (JAXB)

#jaxb #mapstruct #xjc

Вопрос:

Я борюсь с тех пор, как пару часов пытаюсь заставить MapStruct сгенерировать допустимый картограф для классов, сгенерированных JAXB. Особенность этих классов заключается в том, что у них нет ни установщиков, ни сумматоров для коллекций. Например:

 @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IndividualType", propOrder = {"addressTypes","pensionTypes"})
public class IndividualType 
{
  ...
  @XmlElement(name = "addressType")
  protected List<AddressType> addressTypes;
  @XmlAttribute(name = "firstName", required = true)
  protected String firstName;
  ...
  public List<AddressType> getAddressTypes() 
  {
    if (addressTypes == null) {
        addressTypes = new ArrayList<AddressType>();
    }
    return this.addressTypes;
  }

  public String getFirstName() 
  {
    return firstName;
  }

  public void setFirstName(String value) 
  {
    this.firstName = value;
  }
  ...
}
 

У класса avove есть геттер и сеттер для атрибутов (имя в этом примере), но для коллекций (Список здесь) у него есть только геттер. Следовательно, ответственность потребителей заключается в доступе через типы getAddress(добавить (новый тип адреса(…)).

Сопоставитель структуры карты для такого класса выглядит следующим образом:

 @Mapper(collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE, uses = {AddressTypeMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public interface IndividualTypeMapper
{
  IndividualType toIndividualType(IndividualEntity individual);
  @InheritInverseConfiguration
  IndividualEntity fromIndividualType(IndividualType individualType);
}
 

И сгенерированный код структуры карты является:

 @Override
public IndividualEntity fromIndividualType(IndividualType individualType) 
{
  if ( individualType == null )
    return null;
  IndividualEntity individualEntity = new IndividualEntity();
  individualEntity.setFirstName( individualType.getFirstName() );
  ...
  return individualEntity;
}
 

В сгенерированном выше коде инициализируются только свойства, имеющие сеттер, несмотря на использование стратегии TARGET_IMMUTABLE.

Есть какие-нибудь предложения, пожалуйста ? Конечно, простой конструктор идеально подошел бы, но по какой-то причине люди, похоже, предпочитают сложные и нерабочие решения простым рабочим, и, следовательно, я должен использовать MapStruct: — (

Заранее большое спасибо.

Мари-Франс

Ответ №1:

Причина, по которой он не работает, связана с тем, что вы используете CollectionMappingStrategy.TARGET_IMMUTABLE . При этом вы в основном сообщаете MapStruct, что цели моей коллекции неизменяемы и вызовут исключение, если вы попытаетесь изменить коллекцию, возвращенную получателем.

Я бы предложил удалить collectionMappingStrategy его и посмотреть, работает ли он без него.