Last week I found out about a feature that the OpenJPA folks put into their implementation of JPA. But, it is not part of the standard.
That feature is custom fetch plans - And, I think I can safely say that they are my newest favorite thing.
The reason that these are exciting for me personally is that I use JPA to pull data from my back end database that is then converted to XML using JAXB and sent to a browser for processing/display. If I were to transform a completely populated 'top-level' entity, then I would be creating an XML document that could be several Mb.
Until this past week, I thought that I would need to create tailored versions of my JPA entities in order to send back just the part of the XML that I actually needed. Then, I found out about (Cue choir of angels) dynamic fetch plans.
What dynamic fetch plans do is allow you to specify which fields and relations are eagerly fetched at the time that you execute the query. That may not sound particularly earth shattering - but give it time to sink in.
You are able to specify down to the individual database column level exactly what will be pulled from the database (and/or specify the fetch depth). When doing JAXB processing, this allows me (and you if you need it) to tailor the exact data that will be turned into XML.
One poignant example of how this can clean up the XML sent to the browser is to send a list of top level entities for listing in a drop down. The only data that really needs to be sent back is the entity key and description. Without custom fetch groups, JAXB would try to build the entire fully populated entity tree for each entity. The amount of data being sent back to the browser would be insane! My previous solution of creating an array of JPA entity beans in order to define every possible grouping of desired fields was also insane. I picked a middle ground of an overly populous graph that small enough/big enough for most uses and a sparse graph that would be super quick but only useful in one or two cases.
Now, I have been able to remove all of the extra Entity beans. I have simplified the definition of my entity relationships and removed the possibility of missing changes if I change the actual table structures. Plus, I am able to exactly specify what I want to send back in each situation (anywhere from fully populated entities to single fields).
I just wish I had known about them two years ago when I first started using OpenJPA. It would have saved me a lot of refactoring and testing (at a time that I really can't afford to spend the time). But I am glad that I managed to 'stumble onto' them. I didn't really go looking for an EJB 3 entity manager - I just used the one that came with Geronimo. If I had shopped around, I might not have given this the weight it deserves.
And it is -huge-. Not only can you pare down an overly generous eager fetch - you can also expand an excessively lazy fetch - at runtime with very little programming cost.
By the way, the painful part is trying to undo two years worth of hacks to accomplish something that was included in OpenJPA - in five days.
I think I used to sleep - didn't I?