Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unmarshalling JAXB collection when using IDResolver failing because IDResolver Object as target type

Tags:

java

jaxb

cxf

I have this problem trying to unmarshall json from rest webservice (cxf). I'm using JAXB and EclipseLink.

The entity is mapped like that:

@Entity
@Table(name = "service_pkg_service", schema = "MD")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ServicePkgService extends DatabaseModel implements java.io.Serializable {

    @Transient
    @XmlIDREF
    private Set<ChannelPkgService> channelPkgServices = new HashSet<ChannelPkgService>();
}

@Entity
@Table(name = "channel_pkg_service", schema = "MD")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class ChannelPkgService extends DatabaseModel  implements java.io.Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CHANNEL_PKG_ID")
    @XmlID
    @XmlAttribute
    private String id;

}

I have a class extending IDResolver, so I can generate an entity based on its ID.

public class EntityIDResolver extends IDResolver{

@Override
public void bind(String id, Object obj) throws SAXException {
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Callable<?> resolve(final String id, Class targetType) throws SAXException {

    }
}

I have problem unmarshalling json like this "channelPkgService": [1,2,3], the class of targetType is java.lang.Object

I read this https://github.com/javaee/jaxb-v2/issues/546 , and created a wrapper to handle this.

public class ChannelPkgServiceWrapper extends HashSet<ChannelPkgService>{
}

Sinse I have a lot of these cases and I don't want to create a lot of wrappers, is there a more generic way to handle that?

Forget the used versions:

  • cxf.version:2.3.6
  • eclipselink:2.3.0
  • jaxb-impl-2.1.13.jar (jar containing Lister.class that is doing the actual work for getting the correct type.)
like image 904
Manoel Iliev Avatar asked Sep 19 '11 23:09

Manoel Iliev


People also ask

How does JAXB unmarshalling work?

Unmarshal is the process of binding the XML document using JAXB compiler and generating mapping java classes then constructing the instances with values available in XML document. Marshal is the reverse process of it. First we construct the instances and then write a XML document using the constructed instances.

What is JAXB Unmarshalling?

Unmarshal a root element that is globally declared The JAXBContext instance maintains a mapping of globally declared XML element and type definition names to JAXB mapped classes. The unmarshal method checks if JAXBContext has a mapping from the root element's XML name and/or @xsi:type to a JAXB mapped class.

What is unmarshalling in Java?

Unmarshalling is the process of reading XML documents into Java objects. The JAXBContext class provides the client's entry point to the JAXB API. It provides API for marshalling, unmarshalling and validating.


1 Answers

@XmlIDREF is used by JAXB to map intra-document references. Each object referenced by ID must also appear nested somewhere in the XML or JSON document:

  • http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html

If you are looking to marshal an object as its ID, then you will want to use an XmlAdapter. Check out my answer to a similar question:

  • Serialize a JAXB object via its ID?

Also note that JAXB is a specification (JSR-222), and EclipseLink contains the MOXy implementation (I'm the MOXy tech lead). This means you could eliminate jaxb-impl-2.1.13.jar from your dependencies:

  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
like image 140
bdoughan Avatar answered Oct 01 '22 23:10

bdoughan