Problem
JAXB is great for generating JAVA code necessary to support marshalling and unmarshalling of XML to Java Pojo’s particularly when working with web services. However with some WSDL’s the Java code generated contain JAXBElement types instead of Java data types. For example a schema fragment from a Salesforce notification wsdl:
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:sobject.enterprise.soap.sforce.com">
<import namespace="urn:enterprise.soap.sforce.com"/>
<!-- Base sObject (abstract) -->
<complexType name="sObject">
<sequence>
<element name="fieldsToNull" type="xsd:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
<element name="Id" type="ent:ID" nillable="true" minOccurs="0" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="Opportunity">
<complexContent>
<extension base="ens:sObject">
<sequence>
<element name="Sales_Opportunity_Number__c" nillable="true" minOccurs="0" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
would generate the following corresponding Java code fragments:
public class Opportunity
extends SObject
{
@XmlElementRef(name = "Sales_Opportunity_Number__c", namespace = "urn:sobject.enterprise.soap.sforce.com", type = JAXBElement.class)
protected JAXBElement<String> salesOpportunityNumberC;
/**
* Gets the value of the salesOpportunityNumberC property.
*
* @return
* possible object is
* {@link JAXBElement }{@code <}{@link String }{@code >}
*
*/
public JAXBElement<String> getSalesOpportunityNumberC() {
return salesOpportunityNumberC;
}
/**
* Sets the value of the salesOpportunityNumberC property.
*
* @param value
* allowed object is
* {@link JAXBElement }{@code <}{@link String }{@code >}
*
*/
public void setSalesOpportunityNumberC(JAXBElement<String> value) {
this.salesOpportunityNumberC = ((JAXBElement<String> ) value);
}
}
The JAXBElementsalesOpportunityNumberC type is a bit cumbersome to work with your Java code.
Solution
A simple solution to this problem is to edit a copy of your wsdl. Do the following:
- Replace all nillable=”true” to nillable=”false”
The desired side effect of this generating Java code with the desired Java types in place. See corresponding example:
public class Opportunity
extends SObject
{
@XmlElement(name = "Sales_Opportunity_Number__c", namespace = "urn:sobject.enterprise.soap.sforce.com")
protected String salesOpportunityNumberC;
/**
* Gets the value of the SalesOpportunityNumberC property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getSalesOpportunityNumberC() {
return salesOpportunityNumberC;
}
/**
* Sets the value of the salesOpportunityNumberC property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setSalesOpportunityNumberC(String value) {
this.salesOpportunityNumberC = value;
}
}
Props
Brian Dussault and Julie Dougherty word on this problem and came up with the solution documented and currently used by my team.