JEE: Solving the eager fetch or Open-Session-In-View problem

In the JEE architecture entities are used to transfer the data between database and business logic. An object relational mapper like hibernate or toplink the handles the transport of the data form the database table to the entity. The ORM does this not only for the requested object, also all referenced objects could be handled automatically.

The most popular ORMs have very good and popular feature: lazy loading. Using this feature it is possible to fetch an entity by the ORM and referenced objects load their data transparent to the developer during the first access. This feature is great for having a good performance without the need of implementing a specially tailored fetch method for every different case of needed object trees. For example the order object is loaded with the ORM. The referenced customer object is only loaded, when accessing the customer attribute of the order. Same for the different addresses of the customer, the order positions and the data of the ordered items.

This works great using the order-object inside of the business logic in the business layer. But what happens when the order is returned by a service to the view layer? The view needs to access subobjects of the order which not have been needed by the getOrder method of the business layer. Because they have not been accessed they are not initialized yet. Because we have a clean architecture we have defined our transaction boundary above the service layer. When accessing now a not initialized subobject in the view layer the transaction is already closed and you get a LazyInitializationException.

There are three common solutions of the problem:

  • Open-Session-In-View pattern
  • Eager fetch pattern
  • DTO pattern

You can find descriptions of the patterns around in the net e.g. here

The Open-Session-In-View pattern is from the architectural view point very ugly. Loading of data is done in the view layer. Additionally it is very easy to get mysterious effects. For example if an attribute of an displayed object has a value, which is not expected by the view layer and therefor replaced by a default value, it could happen, that during the view of the object an update on the database is triggered.

The Eager fetch pattern means when fetching the order all subobjects are also fetched. This is not possible by declaration in all cases and usually absolutely unnecessary and tends to bad performance.

The DTO pattern converts all entities to DTOs with the same name and attributes when leaving the service. Inside the business layer the entities and lazy loading is used. This works well, but is a lot of stupid code to implement and to maintain.

The ideal solution would be to have an automatic conversation from entities to DTOs when leaving the service. It would be nice to define for each service operation which object tree is guaranteed to be initialized. So lets do it!

First we define an Initialized annotation:

This annotation is used for operations this way:

Now we can define on each operation which parts of the object tree is guaranteed to be initialized. The view layer using this operation can rely on the initialization.  If the view needs in an other case an other combination of initialized objects we  can create a second operation with a different annotation.

In the next step we implement a piece of code, which handles the Initialized annotation and loads the needed objects. Here is an example of an implementation as spring AfterReturningAdvice:

Finally we have to attach the LazyInitialitationVerifyer to every (spring-)service:

Bernhard Mähr @ OPITZ-CONSULTING published at http://thecattlecrew.wordpress.com/

Leave a Reply