Search business objects in enterprise applications using J2EE

J2EE design patterns can help you add a search component to your applications

Search serves the purpose of retrieving a view or list of already persisted instances of business objects for a business scenario. For example, in a bank account system, a typical search would be, List all transactions made during January through June in the years 2000 through 2004 for amounts involving 0,000 or more for all California customers. This search involves a set of related business objects such as customer, credit, debit, transaction, state, account type, and so on. For a medium-sized California bank, this search could retrieve a large result set involving at least a million records. The main difference between the search defined here and transaction handling is that transaction handling works on one business component (a set of business objects linked as a tree), called the model's instance, whereas search typically works with a group of business objects (instances) mainly needed for display/read-only purposes for the clients to see before acting on the results. Now J2EE provides some design patterns to do these types of complex searches.

Even when J2EE was not popular, developers had to endure this problem of searching numerous business objects in enterprise applications. They used JDBC (Java Database Connectivity) calls and wrapped RowSets to develop the search application component in Java. The need for a search component in enterprise applications comes mainly from the usage of relational databases for persistence.

Designing an object-oriented multitiered enterprise application has its challenges in the usage of relational database management systems or any non-object-oriented system as the persistent layer. Enterprise application designers like to use relational database systems because of their maturity. Relational databases are also successful for numerous other reasons, such as volume-handling, transaction-handling, and EAI (enterprise application integration). Object-oriented database management systems (OODBMS) are sparse and also not popular in the industry.

When designing object-oriented systems in Java using relational databases as the persistence mechanism, we abstract business as Java business objects and represent the business objects as tables in relational databases. In J2EE, this abstraction is data access objects (DAO), entity beans, and (sometimes) session beans. The persistence layer (tables) falls below this abstract layer, which is controlled either programmatically using bean-managed persistence (BMP) or, leaving it to J2EE, as container-managed persistence (CMP). This allows J2EE application designers to work without bothering with persistence code; thus, they develop robust enterprise applications using object-oriented methodologies, worrying little about the persistence mechanisms.

Many discussions and articles are available on the transaction-handling systems and OLTP (online transaction processing) systems, but few cover this niche area of search, where doing it the J2EE way could improve your application in terms of response time, security, memory management, and design-patterned code that looks neat and maintainable—which means a lot to us techies.

A design without the search component could have a loophole

A search queries business-object relationship trees for only valid relationships described in your object model design, with restricted access based on your security design. Why is the search component a loophole in your design? Most designers settle for direct SQL (JDBC calls) to solve the search problem, because, simply, a SQL is all that is needed for a search. Direct SQL is simple and elegant, unlike the intricacies of object orientation. The compromises we make if we use direct SQL queries instead of a search component are the following:

  1. Your developers can break your object relationship design by framing culpable relationships ignorantly through joins in SQL queries
  2. Since the records are directly availed from the tables through SQL, security that you designed based on the objects cannot be applied here
  3. As searching deals with large result sets, the design should have provisions to handle, such as better client control and response time
  4. Ultimately you will end up with a separate querying system that is loosely coupled with your transaction system

Search component characteristics

A search component should have the following characteristics:

  1. Querying across business-object component trees, restricting only valid object relationships
  2. On-the-fly lightweight business objects are created because the transactional business objects are heavy and have other business logic methods
  3. Object-relational mapping
  4. Read-only business objects
  5. Security for these lightweight business objects based on the user/role that accesses the search
  6. Business objects that don't involve transaction
  7. Large result sets spread across tables

So does J2EE provide design patterns to do a search component? My answer is a resounding yes.

J2EE design concepts for search

We will now look at J2EE design patterns that can reduce the work to create a search component. Since many resources discuss these patterns in detail, I present only brief descriptions of the patterns and explain how they are useful in completing a search component.

The Value List Handler pattern

Value List Handler is suggested for searching large result sets. Figures 1 and 2 show what we want to do at a 30,000-foot view.

Figure 1. Value List Handler pattern (Source: CoreJ2EEPatterns.com, 2003) . Click on thumbnail to view full-sized image.
Figure 2: Sequence diagram for Value List Handler pattern (Source: CoreJ2EEPatterns.com, 2003) . Click on thumbnail to view full-sized image.

This pattern has a ValueListHandler that creates and manages the lightweight data object result sets. These data objects are your searched business objects. This pattern will be your framework pattern for search. It provides a facility to solve most of the characteristics mentioned above, such as:

  • Handling large results sets and processing them on the server side
  • Better client control and presentation in terms of iterators and sublists
  • Works with data access objects, rather than direct JDBC queries

Data Access Object pattern

The DAO pattern constructs the SQL after doing object-relational mapping and executes to get the result sets. This pattern also restricts access based on the security framework you have designed for the transaction data objects. This DAO creates a data skeleton of the actual business object. Creating the same transaction data objects here would not prove favorable, as they would be heavy and have other business logic methods. Figure 3 shows the Data Access Object design pattern.

Figure 3. Data Access Object design pattern (Source: CoreJ2EEPatterns.com, 2003) . Click on thumbnail to view full-sized image.

J2EE patterns for DAO design

Two J2EE patterns are suggested for your DAO design: Transfer Object Assembler and DAO RowSet Wrapper List (a strategy explained in the DAO pattern).

DAO RowSet Wrapper is the simplest pattern; it is just a business object wrapper over the result set. It will iterate and construct the wrapper business object with relationships and look at security to restrict the results. Transfer Object Assembler is more complex and proves useful if you are doing in-memory searches and searches across different data sources.

To represent the business object model, obtain transfer objects from various components and assemble them into a new composite transfer object. The server, not the client, should perform such on-the-fly construction of the model. So if your objects are large and spread across coarse and fine-grained entity beans, using the Transfer Object Assembler pattern will be more appropriate over DAO RowSet Wrapper.

Search component design is not complete without including the following concepts: object-relational mapping and security.

Object-relational mapping

The search component needs to convert your object relationships to SQL. All the search object relationships definitions are usually defined during design and then, during execution, relational validity is confirmed. The relational query is constructed, converting the defined object relationship to relational joins.

Security

The object instance-based security will be applied at the instance level by the DAO pattern during the processing of the result sets. The security at the object/parameter level can be provided either at the object level or at the SQL level to avoid large result sets. For example, say a user performing the search should not have access to Florida's account details; that constraint can be added to the SQL as a where clause, which would reduce the result sets. Again, based on your requirements and security design, that constraint can also be restricted during the on-the-fly object creation, while constructing the data objects from the results sets.

Conclusion

Most of us have come across the design of a search component in our applications. Since most of us are moving from Java-based systems to J2EE-based systems, designing the search component as described in this article will give us a tightly coupled search system that integrates and reuses the other components, such as transaction-handling and security, which is truly object oriented.

Rajesh Manickadas, being a post-graduate in computer applications, has five years of Java development experience, and three years of experience in product development for enterprise applications. Search is one area where he has worked extensively. Currently he is a technical lead with OrangeScape, an enterprise software product development company.

Learn more about this topic

This story, "Search business objects in enterprise applications using J2EE" was originally published by JavaWorld.

Copyright © 2004 IDG Communications, Inc.