I am using ModelMapper (3.2.0) to map JAXB Beans to my domain beans.
The schema which is used to generate the JAXB Beans contains xs:IDREF elements, which are represented as List<JAXBElement<Object>> in the JAXB Bean.
But ModelMapper doesn't understand how to map the source bean to my target bean - rather it maps the unmapped source bean into the target. In other words, the List<JAXBElement<Object>> in the source - which is a List<JAXBElement<Dokument>> at runtime - ends up in the target as-is.
(Thexs:IDREF is a feature of XML: one can refer to XML Elements elsewhere in the XML document by means of an XML id that is unique in the document.)
Excerpt of the xsd schema:
<xs:complexType name="IdentitaetUndAufenthaltsstatus">
<xs:sequence>
<xs:element name="ausweisart" type="xs:string"/>
<xs:element name="aufenthaltsstatus" minOccurs="0" type="xeb:Aufenthaltsstatus"/>
<xs:element name="dokumentIDReferenz"
minOccurs="0"
maxOccurs="unbounded"
type="xs:IDREF"/>
</xs:sequence>
</xs:complexType>
Here is the generated JAXB bean which matches the schema. Note the type of the attribute dokumentIDReferenz:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IdentitaetUndAufenthaltsstatus", propOrder = {
"ausweisart",
"aufenthaltsstatus",
"dokumentIDReferenz"
})
public class IdentitaetUndAufenthaltsstatus
implements Serializable
{
private final static long serialVersionUID = 100L;
@XmlElement(required = true)
@NotNull
@Valid
protected CodeAusweisart ausweisart;
@Valid
protected Aufenthaltsstatus aufenthaltsstatus;
@XmlElementRef(name = "dokumentIDReferenz", namespace = "https://portalverbund.d-nrw.de/efa/XEinbuergerung/Version_1_4_0", type = JAXBElement.class, required = false)
protected List<JAXBElement<Object>> dokumentIDReferenz;
// ... getters and setters ...
}
What I would like in the target is the following:
public class IdentitaetUndAufenthaltsstatus {
protected String ausweisart;
protected Aufenthaltsstatus aufenthaltsstatus;
protected List<DokumentDto>> dokumentIDReferenz;
// ...
}
ModelMapper is unhappy with that:
1) Unmapped destination properties found in TypeMap[JAXBElement -> DokumentDto]:
de.example.commons.xeinbuergerung.domain.DokumentDto.setDokumentnummer()
de.example.commons.xeinbuergerung.domain.DokumentDto.setAktuelleVersion()
de.example.commons.xeinbuergerung.domain.DokumentDto.setLetzteVersion()
de.example.commons.xeinbuergerung.domain.DokumentDto.setDokumentID()
de.example.commons.xeinbuergerung.domain.DokumentDto.setDokumentTyp()
de.example.commons.xeinbuergerung.domain.Dokument.setDokumentRepraesentation()
I am unable to tell ModelMapper how it should map a JAXBElement<Dokument> into a DokumentDTO.
If I rewrite my target bean so that it expects a List<JAXBElement<DokumentDto>>, ModelMapper does map the field, but it fills in the original List<JAXBElement<Dokument>> instead of List<JAXBElement<Dokument>>.
I have tried to apply a Converter, hoping I could use the ModelMapper engine to map inside the converter:
jaxbElementDokumentConverter = new Converter<JAXBElement<Dokument>,
de.example.commons.xeinbuergerung.domain.DokumentDto>() {
@Override
public de.example.commons.xeinbuergerung.domain.DokumentDto convert(MappingContext<JAXBElement<Dokument>,
de.example.commons.xeinbuergerung.domain.DokumentDto> context) {
return context.getTypeMap().map(context.getSource());
}
};
But it gives me this weird error:
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Disconnected from the target VM, address: '127.0.0.1:56236', transport: 'socket'
org.modelmapper.MappingException: ModelMapper mapping errors:
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:386)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:80)
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:589)
at org.modelmapper.ModelMapper.map(ModelMapper.java:422)
at de.example.xeinbuergerung.v140.business.XEinbuergerungService.getVorgangTransportieren2010(XEinbuergerungService.java:102)
at de.example.xeinbuergerung.v140.business.XEinbuergerungServiceTest.mapToEingangsnachrichtAndGetDigitalerEinbuergerungsAntrag(XEinbuergerungServiceTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit<...>org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:137)
at org.modelmapper.internal.TypeMapImpl.map(TypeMapImpl.java:186)
at de.example.xeinbuergerung.v140.mapper.XEinbuergerungModule$3.convert(XEinbuergerungModule.java:54)
at de.example.xeinbuergerung.v140.mapper.XEinbuergerungModule$3.convert(XEinbuergerungModule.java:50)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:306)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:137)
at org.modelmapper.internal.TypeMapImpl.map(TypeMapImpl.java:186)
at de.example.xeinbuergerung.v140.mapper.XEinbuergerungModule$3.convert(XEinbuergerungModule.java:54)
at de.example.xeinbuergerung.v140.mapper.XEinbuergerungModule$3.convert(XEinbuergerungModule.java:50)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:306)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:137)
I suppose ModelMapper fails to unwrap the JAXBelement automatically. But how to tell it to call JAXBElement.getValue() and then map the result?