Member Menu
 
 Monthly JBoss newsletter:
 
Hibernate Books
CaveatEmptor

Hibernate in a Layered Architecture

This page is used to centralize the issues developers have with a layered architecture and Hibernate as the persistence layer. Usually, you have some kind of service layer on top of the persistence layer. But presentation layers on top vary, with individual problems.

We're talking about the completely decoupled client on this page, not about web-based presentation with Struts running in the same VM as the business facade. Imagine passing persistent objects out-of-process to a client (propably written with Swing and delivered with Webstart). What should be done when the objects come back from the client?

The scope of this includes

  • how to declare the closure of data that can be retrieved by a client (business constraints)
  • how should a client specify what data he wants (graph plans, QBC, HQL)
  • how is data transfered (transport value objects) and how can we have navigation "accross" the cut, i.e., lazy loading of objects once you reach the edges of the loaded graph
  • sending data back from the client to the business layer (possibly bundled with some commands)

If you need both client/server architecture and a clustered setup on the business/persistence side, go with known EJB patterns (data transfer objects/maps, coarse grained session facade, decouple presentation layer with command pattern). We want a good and clean solution for POJO based systems.

See also Distributed Objects With Hibernate

Some thoughts about Distributed Object Frameworks

Forum Postings


I've noticed recently that a couple of different threads in this forum have been talking about how to use Hibernate with a strongly structured layered architecture (*).

A good example is this thread that discusses lazy loading in a layered architecture:

http://sourceforge.net/forum/message.php?msg_id=2153943

In one of the posts Todd Jonker wrote:

"The only solution seems to be to force the higher logic and UI layers to tell the persistence layer exactly what subset of the available data is needed. (Which sounds like a a nightmare!)"

And Gavin King responded with a post that basically said:

"but what other possibility _is_ there?? the whole point behind a layered architecture is that you cant access the lowest layer (the db) from the much higher layers (the web tier). In practice, it isn't a nightmare at all."

I'd like to start a thread discussing practical methods of dealing with this and other issue relating to use of Hibernate with layered architectures.

Our project uses such an architecture and we have some ways of dealing with these problems, but I'd like to canvass other peoples methods of dealing with these kinds of issues when using Hibernate.

Cheers,

Shorn.

(*) - This thread about Hibernate Vs EJB architecture has a good basic definition of the type of layered architecture I'm referring to:

http://sourceforge.net/forum/message.php?msg_id=2153579


Steve Ebersole partially defined his project architecture as:

"service layer defined as stateless session beans; domain layer defined using Hibernate mappings; data-transfer-objects used to communicate between the service layer and clients." -- Steve Ebersole


I found the following in the hibernate mailing list:

http://article.gmane.org/gmane.comp.java.hibernate.devel/1433/

It describes a solution, where the logic for a lazy loading from client to server is contained in a CGLIB-based interceptor that is added to the "hibernated" objects.


Steve Ebersole

Just to expand on the architecture I chose (and have briefly and disjunctly discussed on the forum). Let me first suggest a great book on this subject, written by Martin Fowler, entitled "Patterns of Enterprise Application Architecture". It is extremely insightful, helpful and well written.

It seems that most of the discussion that I have seen on the forums regarding this topic relate to whether the objects mapped in Hibernate should be returned as-is to the clients, or whether some form of abstraction should be used to represent that data (whether XML, DTO, Commands, etc). To me, each approach has pros and cons. In my architecture, I chose the latter using DTOs as the communication medium with the presentation. In brief, my architecture is as follows:

  1. At the bottom tier is a very strong domain layer (mapped using Hibernate). By very strong, I mean that it bundles all the data elements mapped from Hibernate along with a lot of domain logic (see the section discussing business logic vs domain logic in the chapter on the "service layer" pattern in Fowler's book)...
  2. A set of DAOs with static methods for various methods of locating domain objects using HQL or session.load()
  3. A service layer, implemented as session beans for no other reason than for the transaction support as I have to coordinate transactions across JMS, LDAP as well as the DB. This could easily be non-ejb also, possibly using aspects to acheive transaction "cross-cuts".
  4. a set of "assemblers" (again, see Fowler) which are responsible for "molding" domain objects into DTOs and "swizzling" DTO data back into domain objects.
  5. a slew of DTOs which carry data to and from the clients of the service layer.

To me, there are a couple of pros to this type of approach. Number one would have to be the fact that it completely decouples the client from anything that happens behind the service layer, and vice versa. Part of this is not having to worry about things like whether lazy relationships have been loaded when adding a new column to a search result table. Another advantage is that is gives your app a much more defined API feel. The methods exposed on the service layer are the functionality provided by the system to the outside world. And because a lot of the "nitty-gritty" code is hidden away in the DAOs and the assemblers, the service code is very clean. An example would be:

public ContactDTO loadContact( Long contactId )
throws my.PersistenceException
{
    prepareCall();
    try
    {
        return ContactAssembler.buildDTO( ContactDAO.load( contactId ) );
    }
    catch( Exception e )
    {
        throw new my.PersistenceException( "Unable to load contact", e );
    }
    finally
    {
        endCall();
    }
}

The cons mainly deal with the fact that that's a lot of extra classes to code. At a minimum, in a small app, you can assume about a one-to-one correspondence between the domain objects in your app and their various DTO representations; this may be even bigger for larger apps. Why? Mainly it has to do with relationships and avoiding infinite loops. Consider a ContactDTO with a relationship to a CompanyDTO, which in turn has a collection relation to its employees which are ContactDTOs. This is normally handled by having different DTO representations of data with different "loading levels" (similiar to the Lightweight pattern discussed on the Hibernate patterns page). Thus, you now would have something like ContactDTO -> CompanyDTO -> ContactListDTO. And thats not even considering specialty DTOs like report DTOs, etc. Its hopefully pretty easy to see how this can become a lot of extra classes. Luckily, all these DTOs are pretty brainless to create as they are generally very simple Java Beans.


  NEW COMMENT

Hibernate layered architecture 09 Oct 2003, 17:42 gslonim
Steve,
My question has to do with your approach to decoupling the domain 
model from data transfer objects. As I understood it, your hibernate-
mapped domain objects have relationships to other domain objects, as 
the good domain model would. As you said, you might have, in the 
simplest form, say, Users -> Privileges(Set). Since you have 
relationship in the domain model between Users and Privileges, does 
that mean that you have relationships between DTO's? Does that also 
mean that whenever you retrieve User you retrieve Privilege set (lazy 
or not, regardles), and effectively use Assemblers to transfer data 
into DTO's? Does that mean that your user DTO has a set of Privilege 
DTO's? Otherwise how else do you transfer privileges to the client?
That effectively mean that DTO's will have same relationship as domain 
model objects? 
Please elaborate on this subject.
 
another mapping framework? 26 Nov 2003, 01:55 loverde
As strange as it sounds, I think that what is really needed in this type
of layered architecture is yet another mapping framework.  (And by
"needed", I really mean what would be nice.)

In a sense, your "Assembler" classes are exactly that framework.  One
could envision creating an XML mapping based framework that would
"automate" the assembly process, possibly even directly generating the
DTO classes.  If using reflection, CGLIB could also be employed in this
layer for performance gains.

If you are an XDoclet fan, it would also be realistic to develop a set
of XDoclet tags that could generate your DTOs right from your domain
objects (similar to the value object tags for EJBs).

Obviously this is a lot of plumbing, but that tends to be the price of
layered architectures.
 
Re: another mapping framework? 10 Dec 2003, 14:30 christian
On 26 Nov 2003 01:55, loverde wrote:

>As strange as it sounds, I think that what is really needed in this type
>of layered architecture is yet another mapping framework.  (And by
>"needed", I really mean what would be nice.)

CarrierWave (http://carrierwave.sourceforge.net/) is a framework for
that purpose. It is a mix of the DTO, DTO Assembler and various other
patterns. Basically, it decouples the client view of data from the
server implementation of that view. What you get is the ability to
transfer arbitrary object graphs from the server to the client and, much
more exciting, send that graph back to the server after you modify the
objects client-side. Optimistic concurrency checking (versions) is done
on the server side to ensure transaction isolation.

CarrierWave also has nice features that help separating the client
developers from the server developers: On the server side, you just
create "Finders", "Actions" and mark the parts of your domain model
"Imageable" if you want to allow client side copies/retrieval.

The client developers uses this clear interface to program his data
binding logic, that is, what Finders he calls and what objects (copy of
objects, called "Images") he can retrieve and work with.

CarrierWave generates all this for you, the DTO ("Image") classes and
everything, you just mark up your domain model with XDoclet like tags.

The problem is: CarrierWave is not mature. It has been used as an
in-house framework and was made open source later, so it still has a
certain complexity and warts that you wouldn't find in a clean room
implementation of the patterns.

In my opinion, it is currently the best way to have distributed,
multi-layered systems with a rich domain model. Have a look.

(BTW, the new SDO stuff is basically the same, just not as powerful.)
 
DynaDTO 30 Dec 2005, 07:22 mauross
What about DynaDTO, it seams nice.
 
© Copyright 2006, Red Hat Middleware, LLC. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc. [Privacy Policy]