Jaffa Logo
Home Contact Us FAQs Site Map
Source Forge: Homepage Bugs @ Sourceforge Mailing Lists @ Sourceforge Task Manager @ Sourceforge CVS @ Sourceforge
Jaffa Site
Jaffa Runtime
Jaffa RAD


This section will give you a basic overview of the role of the persistence layer, and how it has been architected. It is probably one of the more complex parts of the architecture and for a business application, the most critical. Reliability and Performance are the top two design drivers when it comes to design.

In concept the persistence layer need to provide a transparent way of moving data between a data base and Java objects. This all has to happen within the context of an ACID transaction. The other main driver for the design of the persistence layer is the ability to abstract the actual underlying persistence technology from the business application code. The reason for this is that in the Java/J2EE world there were (as of Feb' 2001) several different schools of thought about to best move data between the database and Java objects. This requirement lead to the development of the 'pluggable persistence engine'.

The other good question we had to answer is 'if J2EE is the way of the future and they have Entity Beans and Container Managed Persistence' why develop a persistence layer?'. There are two answers to this (a) not everyone is developing or requires n-tier distributed transactions and (b) is CMP 1.1 ready for prime time. We now of course have CMP 2.0, which is much better, but still is it ready? Our collective view is that it will get there one day, but until that day we still need systems, and it would be nice if the way we build them today could be reused for CMP when its day comes.

The other consideration we have been making in the design is that the intended use of this persistence layer is within enterprise level systems. What does this mean? Well to us this means a big data model (1000's of tables), big tables (100+ fields), large volumes of data (millions of rows) which makes performance critical. The other thing with a large application is tones of code that will probably take years to write, and therefore should be quick and easy to develop, and not be prone to refactoring whenever the persistence layer is refactored.

Read More... Other Related Documents


When looking at persistence solutions for objects the most common approach is O/R Mapping (Object to Relational Mapping) and that is the approach that we have focused on. In the early days of research we came across two inspirational papers. The first was Scott Ambler's O/R Persistence Layer White Paper that covers all the basics, and complementing that was Martin Folwer's Unit Of Work pattern.

At the time of development there were already commercial solutions like CocoBase and TopLink that could do O/R Mapping and integrated with J2EE Containers for CMP. There were also a few open source projects that could do varying degrees of O/R mapping, some that worked with Containers, some that did not.

As we were intending to provide an open source framework that could work with, or without a J2EE Container, we finally selected the Castor project with its JDO module (as a bonus also comes with a pretty good XML marshalling capability too).

We developed a pluggable persistence engine based on Castor. This worked well, although we had some teething issues with object relationships, and the lazy loading of them. Then with the development of the Castor/JBoss plug-in that enables Castor to work within the JBoss container as a database resource, we developed a second pluggable engine for persistence within the container.

It was then possible to run the same persistence business code develop for stand alone execution from within a session bean, just by flipping a framework property setting...Cool. Of course for an application to be developed such that it can be run standalone or as a J2EE application, it must be using our middleware layer (see later).

The above was a pretty good solution apart from some known issues with Castor JDO, and mediocre performance and one major design assumption...

The design assumption we'd been making all along was that we were developing new domain object models and using that to drive the relational data model. As with good modeling practice all database tables had an OID (object id) key field, which was used for inter-table relationships. This OID was an internally generated number. (Refer to the White Paper as to why this is all a great idea).

As this point in time we'd built a mini application on this basis and were pretty happy with the results. But our next challenge may sound more familiar with what some of you are facing out there...

We needed a solution that would allow our architecture to be used for web-enabling existing application functionality. This 'existing application' comes with its already designed relational data model, and as you can imagine the tables don't all have technical keys, not all the relationships are modeled correctly, not everything is perfectly normalized. It was clear to the group that the current Castor based engine was not a good fit for this.

We decided to take stock of the current architecture and see if it could be re-used. We have a very good transaction manager, we know how Castor does its basic marshalling, we know that we have a performance issue with relationships and lazy loading, we know that having a flexible mapping between objects and tables is a good approach. And from that starting point the 3rd Engine, the 'JDBCEngine' was born. The next step was to complement the engine with tools to convert existing relational models into a set of domain objects and mapping settings, so the that we could take an existing model and move it into our framework in a matter of minutes. A huge time saver !! (See the Tools Section for more details).

In the background of all this, there have been discussions on how to build the next generation pluggable persistence engine that would allow the use of Entity Beans and CMP, and still be transparent to the development of the domain objects and related business functionality.

Key Design Features

  • Pluggable Engines for different persistent implementations

  • Abstracted API's for business logic, such that the code is not Engine Specific

  • Programmatic Query Language. Allow query errors to be compiler errors, not runtime SQL errors

  • Multiple locking strategies for different business requirements

  • ACID Transaction Support

  • Seamless handling of Object Relationships

  • Domain Object Abstraction from the persistent engine implementation

  • Support for same business code using the persistence layer regardless of Web/EJB Container used.

File: index.html, Last Modified: Tue Jul 15 2003 at 4:02:03pm. This site has been built using PPWIZARD