The client brief was pretty straightforward: “We need to persist this class to a Database”. No problem. Hibernate FTW. “Actually, we’d like to use JPA2 to do the heavy lifting”. No problem, we’ll annotate up the domain classes with a few @Entity statements and we’re off. “Oh, and the class we wish to persist is a graph of objects that are dynamically generated via JAXB”. Things are getting a little more complex now.

Converting your WSDL into a set of JAXB classes is super simple: Use your IDE or the very cool Maven Plugin to get you up and running. But annotating those generated classes with JPA annotations on the way through? That’s a little trickier. Fortunately wsimport just invokes the JAXB compiler (xjc) under the cover, and xjc support plugins! You know where we’re going here..

Enter hyperjaxb3. This very slick little library provides an xjc plugin to markup your JAXB classes with JPA annotations. It will even generate your persistence.xml file on the way through. Most importantly of all, it knows how to work around the known incompatibilities between JPA and JAXB (for example, that your xsd:date entries will get marshalled to javax.xml.datatype.XMLGregorianCalendar which is not a supported type for JPA).

Hyperjaxb3 works around things like this by providing @Transient getters and setters for the XMLGregorianCalendar methods, whilst generating native JPA getters and setter for standard java.util.Date classes. Very tricky.

Hyperjaxb will also handle collections cleverly, so List gets marshalled off into its own 1:m table. It means that complex graphs will generate lots of tables, but everything worked for my prototype which was a very complex schema. I’m super impressed.

It took several days to get all the dependencies right, and it did involve copying jaxb and jaxws jars into my jdk1.6.0/jre/lib/endorsed folder - so I thought I’d put up a sample POM below to save you some time. I’m not sure that the approach is even going to work under scale, given the complexity of the graph. I suspect we’d be better off writing a simple JPA wrapper class that we marshall via Dozer but it does give the client their preferred option to explore.

To save you some time, I’ll provide a Sample Maven POM that is wired up for everything you need to get yourself up and running. Just add your favorite IDE and you’re in business. Oh, and don’t forget that /jre/lib/endorsed thing.

Happy transformations!
</p