Search code examples
javajaxbeclipselinkmoxy

Mapping a Java property to several xml attributes using JAXB and MOXy


I have a simple class CustomQuoteRequest:

public class CustomQuoteRequest {

  private String requestId;

  private String currencyPairCode;

  public String getRequestId() {
    return requestId;
  }

  public void setRequestId(String requestId) {
    this.requestId = requestId;
  }

  public String getCurrencyPairCode() {
    return currencyPairCode;
  }

  public void setCurrencyPairCode(String currencyPairCode) {
    this.currencyPairCode = currencyPairCode;
  }
}

I would like to map currencyPairCode to two different attributes in the xml. This is the MOXy mapping file I am using:

<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_1.xsd"
    >
    <java-types>
        <java-type name="com.anz.fxeasy.domain.model.quote.CustomQuoteRequest"  xml-accessor-type="FIELD">
            <xml-root-element name="FIXML"/>
            <java-attributes>
                <xml-element java-attribute="requestId" xml-path="QuotReq/@ReqId"/>
                <xml-element java-attribute="currencyPairCode" xml-path="QuotReq/QuoteReq/Instrmt/@Sym"></xml-element>
                <xml-element java-attribute="currencyPairCode" xml-path="QuotReq/QuoteReq/Leg/Leg/@Sym"></xml-element>
            </java-attributes>
        </java-type>
    </java-types>

However the second xml-element seems to override the previous one. Any ideas? Thanks a lot


Solution

  • EclipseLink MOXy 2.1.X

    In EclipseLink 2.1.X you can use an XML Customizer to accomplish this. Your external metadata would look like the following:

    <xml-bindings
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_1.xsd"
        >
        <java-types>
            <java-type name="forum78.CustomQuoteRequest"  xml-accessor-type="FIELD" xml-customizer="customizer.CustomQuoteRequestCustomizer">
                <xml-root-element name="FIXML"/>
                <java-attributes>
                    <xml-element java-attribute="requestId" xml-path="QuotReq/@ReqId"/>
                    <xml-element java-attribute="currencyPairCode" xml-path="QuotReq/QuoteReq/Instrmt/@Sym"/>
                </java-attributes>
            </java-type>
        </java-types>
    </xml-bindings>
    

    In the customizer we'll add a second mapping for the currencyCodePair property. We will need to indicate that this mapping is write only. The implementation of the XML customizer would look like the following:

    package customizer;
    
    import org.eclipse.persistence.config.DescriptorCustomizer;
    import org.eclipse.persistence.descriptors.ClassDescriptor;
    import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
    
    public class CustomQuoteRequestCustomizer implements DescriptorCustomizer {
    
        public void customize(ClassDescriptor descriptor) throws Exception {
            XMLDirectMapping  currencyPairCodeLegMapping = new XMLDirectMapping();
            currencyPairCodeLegMapping.setAttributeName("currencyPairCode");
            currencyPairCodeLegMapping.setXPath("QuotReq/QuoteReq/Leg/Leg/@Sym");
            currencyPairCodeLegMapping.setIsWriteOnly(true);
            descriptor.addMapping(currencyPairCodeLegMapping);
    
        }
    
    }
    

    EclipseLink MOXy 2.2

    In the upcoming EclipseLink 2.2 release you will be able to do this using just the externalized metadata:

    <xml-bindings
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_1.xsd"
        >
        <java-types>
            <java-type name="forum78.CustomQuoteRequest"  xml-accessor-type="FIELD">
                <xml-root-element name="FIXML"/>
                <java-attributes>
                    <xml-element java-attribute="requestId" xml-path="QuotReq/@ReqId"/>
                    <xml-element java-attribute="currencyPairCode" xml-path="QuotReq/QuoteReq/Instrmt/@Sym"/>
                    <xml-element java-attribute="currencyPairCode" xml-path="QuotReq/QuoteReq/Leg/Leg/@Sym" write-only="true"/>
                </java-attributes>
            </java-type>
        </java-types>
    </xml-bindings>
    

    The following bug can be used to track this support: