简体   繁体   中英

Jaxb Unmarshalling of List of abstract Objects

I've been stuck on this problem for a while and was hoping to get a push in the right direction. I am trying to properly marshall a complex object, everything is properly exported to XML except one specific relationship. I am using Spring @Endpoint implementation.

The class causing me issues is the AbstractDependent.

My model is as follows (example code):

@XmlRootElement
public class RootClass{

    private Set<AbstractClassA> classASet;
    private Client client;

    //... getters/setters (no special annotations)
}

@XmlRootElement
public class Client extends AbstractApplicant{
    private List<AbstractDependent> dependentList;

    //..more attributes... setter/getters
}

@XmlRootElement
public class Child extends AbstractDependent{
  //class attributes
}

@XmlRootElement
public class Spouse extends AbstractDependent{
  //class attributes
}

//tried putting the @XmlSeeAlso annotation, no success
public abstract class AbstractDependent extends AbstractApplicant{
  //class attributes
}

public abstract class AbstractApplicant{
  //class attributes
}


//No Special annotations
public abstract class AbstractClassA{
  //class attributes
}

//The only special annotation is the XmlRootElement, other attributes are atomic
@XmlRootElement
public class ImplA extends AbstractClassA{
  //class attributes
}

All classes are in the same package, I use the package-info.java file to specifiy the namespace.

I've inspected the marshaller in spring's MarshallingPayloadMethodProcessor and the JaxB context includes all classes mentioned above, so this is not the issue.

On a side note, implemented classes of AsbtractClassA are fine and get properly translated in xml with the "type" attribute. Here is an example of the output:

<?xml version="1.0" encoding="UTF-8"?>
<ns3:rootClass xmlns:ns3="http://mynameservice.com/schema/webservice">

    <ns3:abstractClassA xsi:type="ns3:implA">
        <id>1</id>
    </ns3:abstractClassA>
    <ns3:abstractClassA xsi:type="ns3:implB">
        <id>2</id>
    </ns3:abstractClassA>

    <ns3:client>
        <id>15</id>
        <ns3:dependentList>
        <id>17</id>
        <!-- other attributes -->
        </ns3:dependentList>
        <ns3:dependentList>
        <id>18</id>
        <!-- other attributes, excluding the ones from the Child And Spouse class  -->      
        </ns3:dependentList>
    </ns3:client>

</ns3:rootClass>

The xsi:type is properly defined on AbstractClassA , but not on the AbstractDependent , and I can't seem to understand why or how. Evidently my model is much larger than this, but the dependentList is the only elements causing me issues. It is worth noting that putting the @XmlTransiant element on the dependentList does not help at all, it excludes the object entirely from the xml (many internet posts suggested doing this).

The marshaller defined is as follows, again the context includes all necessary classes:

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="packagesToScan">
        <list>
            <value>com.company.*</value>
        </list>
    </property>
</bean> 

Some configuration:

<bean id="messageReceiver"
    class="org.springframework.ws.soap.server.SoapMessageDispatcher">
    <property name="endpointAdapters">
        <list>
            <ref bean="defaultMethodEndpointAdapter" />
        </list>
    </property>
</bean> 

<bean id="defaultMethodEndpointAdapter" 
    class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
    <property name="methodReturnValueHandlers">
        <list>
            <ref bean="marshallingPayloadMethodProcessor"/>
        </list>
    </property>
    <property name="methodArgumentResolvers">
        <list>
            <ref bean="marshallingPayloadMethodProcessor"/>
        </list>
    </property>     
</bean>  

<bean id="marshallingPayloadMethodProcessor"
    class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
    <constructor-arg ref="jaxbMarshaller" />
    <constructor-arg ref="jaxbMarshaller" />
</bean> 

I would appreciate a push in the right direction, thank you very much!

I found the issue after many hours of investigation. It was due to hibernate passing still lazy-loaded object to the MarshallingPayloadMethodProcessor. I had just assumed that objects would be properly initialized before being marshalled.

I created a custom XmlAdapter:

public class HibernatetEntityAdapter extends XmlAdapter<AbstractEntity, AbstractEntity> {

@Override
public AbstractEntity unmarshal(AbstractEntity v) throws Exception {
    return v;
}

@Override
public AbstractEntity marshal(AbstractEntity v) throws Exception {
    return HibernateUtils.unenhanceObject(v);
}

}

Now I simple add the following annotation on classes which causes me problems:

@XmlJavaTypeAdapter(HibernatetEntityAdapter.class)

Thanks, JP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM