I have to design a data model (in a Java EE 6 application) that will be persisted via JPA, and that also needs to be serialized via JAXB. The last time I did that, I had one group of entity classes with JAXB annotations, and another with JPA annotations. This meant that I had to have a lot of boilerplate code for translating between the two. I'm thinking of combining them, so that each class will have both types of annotations. I know this can be done, but my question is, should it be? Will it cause any problems?
The question is a little too broad for me to answer. But I do have specific related experience using Jackson under JAXB with JPA entities that you might find interesting.
In my case, I had a JPA model with roughly three dozen entities and lots of cyclic references. The graph of relationships between entities was also almost strongly connected. In other words, it was possible to navigate to nearly any entity in the set from any other by following entity relationships. In my case, with entities as described and Jackson 1.5, overlaying JAXB annotations on my JPA entities turned out to be a bad idea.
For one thing, Jackson 1.5 got into infinite recursion on the cyclic references. I consider that operator error rather than a bug. Jackson is awesome software. Also, I think the upcoming 1.6 release provides new features to handle this per JACKSON-235. So this might be moot soon!
My other difficulty related to serialized compactness in the face of strongly connected entities. Serializing all my entity relationships was impractical. I would have serialized an obscene amount of irrelevant information in every request by naively following all entity relationships to their full depth.
I wanted to specify multiple serializations of my JAXB objects, choosing one with appropriate fields and relationships depending on the intended use. But, as far as I'm aware, JAXB and Jackson offer no such flexibility. They offer significant flexibility in defining the representation -- what's transient, how lists look, etc. -- but I don't think multiple representations are possible for one object. Maybe there's a clever way to define multiple representations under JAXB or Jackson and switch at runtime... I'd be interested to learn if such a thing exists. Perhaps there's a feature for this that I'm ignorant of, or some trickery that can be played with subclassing. But I couldn't find it, so ultimately I gave up and went with DTOs.
Again, this is all pretty specific to the model. Maybe these are non-issues for you (or maybe you have clever solutions for these problems!)
This can definitely be done. I actually find the prospect of maintaining code to copy between the models more problematic.
EclipseLink is a great choice for this application as it contains both a JPA (EclipseLink is the RI and open sourced from TopLink), and a JAXB implementation.
EclipeLink JAXB (MOXy) also contains a number of extensions for mapping JPA entities to XML:
- XPath base mappings
- Mapping bi-directional relationships (using @XmlInvereseReference)
- Handling composite key relationships
- Handling embedded key classes
- Handling java.sql.* types
For more information see:
DataNucleus allows persistence using JPA to RDBMS (using JDBC behind the scenes) and XML (using JAXB behind the scenes). It can interprete your JPA annotations as defining how the JAXB serialisation is performed - you could add JAXB annotations too if you so wished