NEOS, LLC. (a previous employer,) specializes in modernizing business processes and technology. The following issues and solutions are fairly common in that kind of effort, especially when porting from an older system where complex queries already exist and no one wants to change them or tune for other scenarios. While this may not apply to your software effort, it does ease a lot of pain when solving certain niche problems. Also, see Java Hair, the technical blog of a few folks at NEOS.
Let’s start with a disclaimer – there are few perfect things and I don’t claim this is one of them, I just know that this works really well and I hope it helps someone else. I also don’t know if anyone’s named this pattern already. If so, let me know. Also, if there are any suggestions for better names, like “Lightning Bolt,” I’m all ears.
The Problems this Pattern Solves
Typically in a J2EE project involving Hibernate, the developers will encounter a situation where there are two or three conflicting needs. If they’re not specifically in conflict, these needs at least make the job a little difficult.
On one hand, there is a need to tune the Hibernate settings of an Entity bean to perform well in queries and take up minimal memory while executing the least number of sub-queries. On the other hand, there is a need for the Hibernate object to be editable and serializable in its original form, meaning that in some cases all data must be available and non-lazy. A third possible need is that somewhere out there is an Oracle/SQL Server/MySQL etc. DBA who is going crazy trying to tune for all the different ways Hibernate is generating queries. While each of these problems is reasonable on their own, solving all of them simultaneously (while doable,) takes up more effort than it should.
In other words, the following pattern allows the developer to solve all three problems with minimal effort on his or her part and minimal effort on the part of the DBA. Everybody’s happy, though I have heard complaints from Java purists. My response to purism is usually the same, whether it’s over-normalizing a database or writing software: “Purism and strict adherence to design doctrines are a means to an end, they are NOT the end. The end result should be cost effective deployment of a working application that can be maintained.” Sometimes I don’t actually say all of that, I may just mutter under my breath and go to refill my coffee.
How this Pattern Came to Be
Having been the software architect on several efforts where the above problems manifested (including one where Hibernate staff were involved and liked the approach,) this really didn’t become a standard until I was exposed to Oracle ADF. I like ADF quite a bit, it is a very short path to delivery and to a developer or business owner that means some good things. What caught my eye was that the ADF framework separated Entity objects from View objects. In ADF, an Entity object represents a table just like a Hibernate POJO usually represents a table. However, Entity objects proper are hardly ever shown in Lists of Values, Search results and so on. Instead, ADF abstracts the Entity objects with View objects. An ADF View object allows a layer of complexity or simplicity to built on top of one or many Entity objects, or it can be built using only a query as its source.
I decided that if it were a good idea for a core product and I’d made a similar concept work in my past projects, then maybe it was time it became a well defined solution to the aforementioned problems. The solution below isn’t exactly like ADF’s pattern. With ADF, View objects make reference to the underlying Entity objects. In the following pattern, we make an effort NOT to.
What it Is
The concept is very simple in practice. Hibernate mappings and beans are created as usual. However, when it comes time to run queries or search for data, a separate object is used. This second object is a Hibernate object that is not mapped to a table. Rather, it’s an object that includes one or more native SQL queries which alias columns. This has several benefits.
- A DBA can easily tune queries that return more than one result
- The Hibernate persistence context doesn’t need to track changes to the objects
- The objects are immediately detachable without ever needing to worry about lazy loading.
- The original entity can be tuned for any kind of eager or lazy fetching. This is especially useful if one isn’t using (or doesn’t want to deal with,) an OSIV pattern.
To get these benefits, a few simple rules must apply to the View/DTO object.
- Don’t map the object to a table
- Don’t create more than one hibernate object to represent query results -in other words, NO relationship objects. No many to ones, no one to many… you get the idea.
There may be obvious exceptions to these rules and these are just the broad strokes. Usually when I implement this pattern I create a common abstract method in the View object that will allow a developer to get back a valid Serializable key for use in opening up a real Entity object for editing. In my implementations I usually call that method “getEntityPrimaryKey()” which returns a Serializable. Then I just pass that result to a simple Hibernate get or load operation and work with the Entity.
To reiterate: the purpose here is allow for peaceful coexistence between DBA approved queries, possibly massive search result tuning for various displays and individual tuning for editable objects.
How you choose to implement the pattern is up to you, but if I receive a few requests for examples, I’ll gladly post them here.