Using JAXB in Hibernate to store java objects as XML documents
In this post, a custom Hibernate type is described that uses JAXB 2.0 to store java objects as XML documents in a database, enabling database clients implemented in other technologies to easily process to stored objects.
Hibernate gives the possibility to serialize java objects and store them as byte array in a database. Applications storing serialized versions of java objects may not be interoperable, since every client accessing the database should be able to deserialize the stored java objects. This will not be the case for a database clients written in Delphi or C#.
It is possible to solve the foregoing problem by saving a XML representation of the java object rather than a serialized one. For this purpose, i have written a custom hibernate type that serialize java objects in xml. The serialization process is performed using JAXB 2.0 (Java Architecture for XML Binding).
JAXB cannot serialize every given object in a XML String. The candidate object must be correctly annotated in order to be xml serialized by JAXB.
To learn more about JAXB Annotations, please visit this site:
The issue you will probably encounter in production case will be non annotated but compiled java classes from third party library that are therefore not eligible for XML Serialization with JAXB. One may extend the java class and try to annotate the different fields of the class and the class itself. But this solution means a lot of refactoring and additional classes. Another solution proposed by JBOSS developers is JAXBIntroduction. JAXBIntroduction or "JAXB annotation introduction" is a JAXB RI features that inserts JAXB annotations at runtime into a java object. You can therefore define java annotations in an external files for non annotated java classes.
Now assuming we java objects that are eligible to be serialized using JAXB. I present a custom Hibernate type, that will use JAXB 2.0 to serialize the java objects and store them as sql:text.
To create your own Hibernate type, we have to implement the interface
org.hibernate.usertype.UserType. Our type will need some external parameters to initialize the JAXBContext. So we also have to implement org.hibernate.usertype.ParameterizedType in other to provide our implementation with external parameters.
The parameters needed by our custom type for the initialization of the JAXBContext are the name of the packages used by JAXB and the full name of the class being serialized. For example, the Hibernate
mapping for an object will look like this:
Here is the source code of the custom hibernate type:
The implementation is quite simple to undertand and to modify if you are introduced with Hibernate.
The XML Document is saved as sql:text in the database. Be sure your SQL Dialect support sql:text type or you may have to extend your dialect to avoid runtime errors.
You will notice that a JAXBContext pool is used to save JAXBContexts for later reuse.
This code is compatible with any JAXB implementation.
Feel free to copy and reuse this code and especially to send me your improved one.
This is a snapshot of the package exployer of the eclipse project used to develop and test the serializer.
If you want to reuse it, you will have to provide all the libraries listet in the package exployer. You can find all that libraries in your Hibernate download and in your j2ee application server download. I used Glassfish in this case.
The librarie glueType.jar is not needed: it provides some objects that
I used as example.
The example use postgresql as database.
Download the whole eclipse project here.
Based on the comments you sent me, part of the code have been optimized: Thank you cliffwd