views:

1437

answers:

3

I am exposing a web service using CXF. I am using the @XmlID and @XmlIDREF JAXB annotations to maintain referential integrity of my object graph during marshalling/unmarshalling.

The WSDL rightly contains elements with the xs:id and xs:idref attributes to represent this.

On the server side, everything works really nicely. Instances of Types annotated with @XmlIDREF are the same instances (as in ==) to those annotated with the @XmlID annotation.

However, when I generate a client with WSDLToJava, the references (those annotated with @XmlIDREF) are of type java.lang.Object.

Is there any way that I can customise the JAXB bindings such that the types of references are either java.lang.String (to match the ID of the referenced type) or the same as the referenced type itself?

A: 

The following seems to at least create string properties for elements/attributes of type xs:IDREF. A good start, but ideally JAXB would generate properties of the same type as the element being referenced. I'll report back if/when I find out how to do that. This result may indicate that I need to write my own converters which would be a shame.

<jxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
        <jxb:globalBindings>
         <jxb:javaType name="java.lang.String" xmlType="xs:IDREF" parseMethod="javax.xml.bind.DatatypeConverter.parseString" printMethod="javax.xml.bind.DatatypeConverter.printString" />
        </jxb:globalBindings>
</jxb:bindings>
kipz
A: 

OK, so this isn't going to work. It's not possible for JAXB to generate code with the correct types for the IDREFs because the schema can't specify the types of references and there may be IDREF's pointing to different complex types. How would JAXB know what are the types of the references? An extension to XML Schema would do it! :)

kipz
A: 

Use the inline JAXB bindings to indicate the type to be used. Then JAXB generated code will have correct type.

<complexType name="Column">
    <sequence>
        <element name="name" type="string" maxOccurs="1" minOccurs="1"></element>
        <element name="referencedColumn" type="IDREF" maxOccurs="1" minOccurs="0">
            <annotation>
                <appinfo>
                    <jaxb:property>
                        <jaxb:baseType name="Column"/>
                    </jaxb:property>
                </appinfo>
            </annotation> 
        </element>
    </sequence>
    <attribute name="id" type="ID" use="required"></attribute>
</complexType>

Also note that you have to declare the jaxb namespace and JAXB version in the schema element.

<schema targetNamespace="http://example.com/schema" 
    elementFormDefault="qualified" 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    jaxb:version="1.0">
abhin4v