Friday, September 05, 2008

AnyType object over webservice and Hibernate

Recently I came across a requirement of moving objects over the network using web services (JAX-WS 2.1). The application was CRUD in nature and Hibernate was used as data tier on the server. In case of web service usually we have WSDL, which clearly defines the kind of objects it expects in request and response. So we can have add/modify/delete/retrieve methods for each type of entity in the WSDL. This approach seems to be doable when we have very few entities. But in our case we were having too many entities and the WSDL was going to be very huge and repetitive in nature. Then what is the way out!!!

I created a base class say BaseEntity.java, which is just a place holder having no variables or methods. Each entity was made to extend BaseEntity.java. The methods in web service interface were having signature like-

@XmlSeeAlso( { MyActualEntity.class })
public interface DataService {

   public void add(BaseEntity object);
}
In the implementing class of the web service interface, Hibernate can determine the actual class name handles that properly to insert the data in correct table. So all seems to be set on the server side, what about client side?

After generating client side stubs when I tried to add an instance of MyActualEntity.java, JAXB complaint that it does not know anything about MyActualEntity. JAXB was absolutely right, it knows only about those data types, which are mentioned in WSDL and MyActualEntity was not part of the WSDL. Then how shall I tell the JAXB about the real entities :-/

We can add the complexType definitions for all entities in the WSDL, but lazy resisted that ;-)
After doing some research I found @XmlSeeAlso annotation., which can be applied on the web service interface. When wsgen task encounters the @XmlSeeAlso annotation, it will include those classes in the WSDL. Now JAXB knows about MyActualEntity and sends that across the wire.

Seems to be a good trick :-)

0 Comments: