Currently, I am working on a project working with JEE (including JPA), and GWT as core technologies. These technologies were chosen among a set of different options because of their qualities, where ease of development was one of the primary targets. The following diagram illustrates the basic tiers of this architecture.
Now, there is a tricky side to these so-called “simple” technologies. Basically, when you work with JPA you have to define a set of entities which becomes the domain language in your application. If this entity model becomes your domain language, it must:
- Provide the basis to define the database schema supporting the system.
- Define the terms of how the business logic is to be realized. In other terms, the domain language helps us define the system’s business rules and scenarios.
The problem/advantage of any RIA application is that part/all of the presentation logic is displaced to the client’s machine. This is done in order to improve usability and decrease the memory and processing spent by the server when rendering presentation to the client. It also brings the dilemma of how to handle data transfer, specially in JPA where you would have to create an additional layer of data transfer objects along with a dto-to-jpa mapper to handle business logic. The problems arising from this approach are the following:
- Ease of maintenance decreased because DTOs represent an additional layer to be managed by the development team. The JPA entity model is evolutionary, and so the DTO layer will have to evolve with it.
- Complexity increased, because the domain language becomes a flattened layer of Javabeans designed to handle the latency restrictions imposed by a RIA model, which means that presentation developers will deal with a twisted version of the actual domain language. Also important is the fact that a managed JPA entity cannot travel to the presentation tier.
So, an additional layer of DTOs (if the application is big enough) can lead to a whole new level of complexity and maintenance that we did not want to get into. The workaround to these problems arrived from an article published by Adam Bien titled Lean service architectures with Java EE 6 where he proposes a Model 2 approach (boundary-controller-entity) using JPA and Stateless Session Beans. This solution defines a Session Facade bean as the boundary for a component, a regular Stateless Session bean as the controller, and JPA entities backing the business logic. Trying to adapt this pattern to architect our system, we realized that it could provide us a way to use our JPA domain model as the layer of DTOs mentioned above to increase ease of maintenance/development and keep complexity within bounds. See the following diagram for details.
You may see that beyond the business tier, all entities must be detached since a managed JPA entity brings with it proxies and other harnesses the JPA Engine uses to sync them up with the database. The business tier is divided into two kinds of service to preserve the boundary-controller-entity model. The facade (which represents the boundary in this approach) picks up the managed entities to be returned and creates a copy for each one of them. Each copy is deep enough for the presentation to perform its work. Whenever a detached entity is received by the facade, a managed version of it is extracted to be used by the stateless/stateful service to perform its business logic.
We have experienced improvement in the development process thanks to this approach. Of course, if you use the additional layer of data transfer objects, you can also benefit from Model 2 by allowing the boundary services to create all DTOs necessary for the application to do its job. I have read about different approaches including the definition of detachment logic having an xml datasource describing such information. You can read more about it in Sanjiv Jivan’s blog. You are welcome to post your comments regarding this subject.