AnsweredAssumed Answered

Desirialization of JPA process variables via REST

Question asked by kaihuener on Jul 1, 2013
Latest reply on Oct 27, 2014 by jbarrez
Hey – I am trying to deserialize a JPA process variable via the new REST API (amazing work, by the way). I am using Hibernate for JPA and Jersey for deserialization.


import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;

Client client = Client.create();
final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(username, password);
client.addFilter(authFilter);
WebResource r = client.resource(url);
ClientResponse response =  r.get(ClientResponse.class);
BusinessPartner bp = response.getEntity(BusinessPartner.class);


But when I run the code, Jersey tells me that a "message body" or something is missing for deserialization.


SEVERE: A message body reader for Java class cdq.cdl.bpr.datamodel.BusinessPartner, and Java type class cdq.cdl.bpr.datamodel.BusinessPartner, and MIME media type application/x-java-serialized-object was not found
Jul 01, 2013 1:22:53 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General


Do I have to add something special to my serialized bean? I would expect Jersey (bundle version 1.17) to handle all the deserialization without additional information?

Maybe – and this is why I ask it here – I missed to tell Jersey the way the bean is serialized by Activity, I mean something like

ClientResponse response =  r.type("application/json").get(ClientResponse.class);

I mean the "application/json" part. Do you use some special type hear?

Just to be complete, this is the serialized class that is not properly deserialized:

package cdq.cdl.bpr.datamodel;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.envers.Audited;

import cdq.cdl.bpr.shared.Constants;

@Audited
@Entity
@Table(name="BusinessPartner")
public class BusinessPartner extends ValidatableEntity implements Serializable {

   private static final long serialVersionUID = -4791687256196212218L;

   private String id;
   private String name;
   private BusinessPartnerType type;
   private BusinessPartner parentBusinessPartner;
   private LegalData legalData;
   private Set<Address> addresses;   
   
   // Metadata attributes
   private String dataSteward;
   private Set<String> subscribers;

   public BusinessPartner() {
      super();
      addresses = new HashSet<Address>();
      subscribers = new HashSet<String>();
      legalData = new LegalData();
   }

   @Id
   public String getId() {
      return this.id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public String getName() {
      return this.name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public BusinessPartner getParentBusinessPartner() {
      return parentBusinessPartner;
   }

   public void setParentBusinessPartner(BusinessPartner parentBusinessPartner) {
      this.parentBusinessPartner = parentBusinessPartner;
   }

   public void setParentCompany(BusinessPartner parentBusinessPartner) {
      this.parentBusinessPartner = parentBusinessPartner;
   }
   
   @ManyToOne
   @Cascade(CascadeType.ALL)
    @JoinColumn(name="businessPartnerType")
   public BusinessPartnerType getType() {
      return type;
   }

   public void setType(BusinessPartnerType type) {
      this.type = type;
   }

   @OneToOne
   @Cascade(CascadeType.ALL)
   public LegalData getLegalData() {
      return legalData;
   }

   public void setLegalData(LegalData legalData) {
      this.legalData = legalData;
   }
   
   @ManyToMany
   @Cascade(CascadeType.ALL)
   @Fetch(FetchMode.JOIN) // Slows down, but required (to be checked …) to load all addresses also after adding a new address
   @JoinTable(name = "BusinessPartnerAddresses", joinColumns = { @JoinColumn(name = "businessPartnerId") }, inverseJoinColumns = { @JoinColumn(name = "addressId") })
   public Set<Address> getAddresses() {
      return addresses;
   }

   public void setAddresses(Set<Address> addresses) {
      this.addresses = addresses;
   }

   public String getDataSteward() {
      return dataSteward;
   }

   public void setDataSteward(String dataSteward) {
      this.dataSteward = dataSteward;
   }

   @Cascade(CascadeType.ALL)
   @ElementCollection
   public Set<String> getSubscribers() {
      return subscribers;
   }

   public void setSubscribers(Set<String> subscribers) {
      this.subscribers = subscribers;
   }
   
   public String toString() {
      String retval = "";
      
      retval += name;
      if (type != null && type.getName().equals(Constants.BusinessPartnerType.LEGAL_ENTITY)) {
         retval += " " + legalData.getLegalForm();
      }
      if (retval.equals("")) {
         return "new business partner";
      }
      return retval;
   }
}


Hope you can help before I have to test all available types …
Thank you in advance and best regards,
Kai

Outcomes