Where to Perform Data Access

Now that we've considered some major data access issues, let's consider the key architectural decision of where to perform data access in a J2EE application.

Let's survey the options for accessing data sources in J2EE. We'll look at the recommended options in more detail in later chapters.

Data Access in the EJB Tier

Most books on J2EE recommend performing data access from EJBs. In a distributed J2EE application this is sound advice; in this case, code in the distributed web containers should depend only on the architectural tier directly beneath them (the remote EJBs), and not communicate independently with data sources. However, in collocated applications there is a less compelling case of performing data access from EJB.

The advantages of performing data access from EJBs are:

  • We have the option of using entity beans

  • We can benefit from CMT. Transaction management is essential to most data access, so this is a major plus

  • All data access will occur through a single tier

The disadvantages are all the drawbacks of EJB (such as complexity) we've previously discussed, plus the serious consideration that data access code is likely to be hard to test, as it depends on an EJB container. Let's look at the options for data access in the EJB tier.

Entity EJBs

An entity bean is a standard J2EE component intended to support access to persistent data. An entity bean layer formalizes the good design practice of decoupling business logic from persistence logic. It is (at least theoretically) independent of the underlying data source. Whatever data source we use, a layer of entity beans objectifies it. In this model, entity beans will expose local interfaces, while the business objects will normally be session beans. However, any objects collocated in the same JVM can work with the entity beans through their local interfaces.

Entity beans are a very basic O/R mapping solution. While they are guaranteed to be available by the EJB specification, they neglect most of the O/R mapping challenges we listed earlier. Object inheritance is forbidden. Data can only come from a single table. Entity beans don't allow us to access aggregate functions in the database without writing custom code, effectively subverting the abstraction they exist to provide. However, EJB 2.0 CMP does support object relationships (EJB 1.1 did not).

Important 

Entity beans in EJB 1.1 have limited functionality, and inferior performance, compared with entity beans written with the EJB 2.0 CMP contract As the CMP 2.0 contract differs from the CMP 1.0 contract, CMP entities require code changes to migrate from EJB 1.1 to EJB 2.0. When using an EJB container that does not support EJB 2.0, don't use entity beans.

Although given the special blessing of the EJB specification for data access, entity beans are perhaps the most controversial technology in J2EE. We'll discuss the pros and cons of using entity beans in more detail in the next chapter, but the following disadvantages rule out their use to solve many J2EE data access problems (some of these disadvantages apply to any simple O/R mapping):

  • Using entity beans reflects sound design principles by separating business logic from data access, but it locks us into a particular implementation of this approach that will affect code in business objects. Working with any type of EJB is more complex than working with ordinary Java objects.

  • They are the only persistence strategy that is only available to EJBs. We're forced to use EJB, whether it's appropriate on other grounds or not.

  • Entity beans with BMP have serious and intractable performance problems, which we'll discuss in the next chapter and which preclude their use in many cases.

  • The entity bean lifecycle is rigid. This makes it difficult to implement coarse-grained entity beans.

  • Using entity beans may tie us to an RDBMS schema. If we use a one-to-one mapping from entity beans to RDBMS tables, we'll have a lot of work to do if the schema ever changes.

  • Using fine-grained entity beans makes it difficult to use relational databases efficiently; for example, it will be difficult to update multiple rows in one statement, as entity beans push us in the direction of mapping to individual rows.

  • Compared with more established O/R mapping solutions, entity beans (even with EJB 2.0 CMP) offer very basic functionality.

  • There are serious questions regarding the performance of entity beans in most EJB containers.

  • The portability advantages of an entity bean solution are debatable. Locking and concurrency behavior is very different between leading databases. Given that EJB containers normally delegate these problems to the underlying database to achieve higher throughput, the abstraction provided by entity beans may actually prove misleading if we port it.

  • Compared with the payoff for using session beans (transparent thread, security, and transaction management for limited deployment complexity), adopting entity beans delivers a more questionable payoff, for significantly greater deployment complexity.

The essential contradiction in using entity beans for data access is arguably that EJBs - due to the complexity of accessing them and their relatively heavyweight nature - are best considered as components, rather than ordinary objects. Data access usually requires much finer granularity than EJBs can efficiently deliver.

Important 

Entity beans can be effective in some J2EE architectures, but they're not the ideal abstraction between business logic and physical data store. If session beans access entity beans directly, session beans risk becoming tied to a particular schema. It's also hard to replace the entity bean layer with another approach if performance proves to be a problem.

Session EJBs and Helper Classes

Even if we choose to use EJB and implement business logic in session EJBs, we're not forced to use entity beans for data access. Session EJBs are business logic components. This means that they shouldn't deal with the details of data access.

However, this leaves the option of using session beans to control data access, and using the DAO pattern to abstract the details of that access. This is a very flexible approach. Unlike using entity beans, which commits us to one approach, we retain control of how persistence is handled. DAOs can use any persistence API, such as JDO, JDBC, a proprietary mapping framework, or even entity beans. This flexibility (and the reduced overhead compared with the entity bean infrastructure) often leads to better performance than using entity beans.

The only difference between using the DAO pattern from session beans and from other types of business object is the availability of declarative transaction management. Often the same DAOs will work inside or outside an EJB container.

Note 

This approach is sometimes referred to as Session Managed Persistence (SMP), in contrast to entity bean CMP and BMP. I don't much like this term, as it implies that the persistence code is actually contained in session beans - a poor implementation choice. Also, the DAO approach isn't tied to the use of EJB.

Data Access in the Middle Tier without Using EJB

As we've seen, J2EE web applications can have a distinct middle tier of business objects without using EJB (EJBs are the only choice for the middle tier in distributed applications with remote clients). This means that we can have middle tier business objects running inside a J2EE web container, but which are not web-specific (in fact they can also support remote access via web services). Such objects have access to programmatic global transaction management with JTA, and connection pooling (J2EE web containers, like EJB servers, provide connection pools, accessible to user code with JNDI lookup. This means that we don't need to use an EJB container to access enterprise data).

Such business objects can use any data access strategy available to J2EE applications. Typically, they will use an O/R mapping framework, such as JDO or TopLink, or a resource-specific API, such as JDBC. They lack the option of declarative transaction management, but this approach offers good performance (as it avoids the overhead of EJB) and is easy to test. Typically, data access objects used in the web container depends only on the ability to access aJDBC datasource viaJNDI or an O/R mapping framework. Such requirements can easily be met by test harnesses, unlike EJB container services.

Such data access without EJB is a good option for collocated applications when:

  • We don't want to use EJB. As we've seen, the data access benefits of EJB do not usually justify using EJB where it would not otherwise be considered.

  • Data access is non-transactional. In this case, EJB CMT delivers no benefit.

  • Some functionality related to data access (such as data caching requirements) conflicts with the programming restrictions applying to EJBs. In this case, it may be simpler to combine the data access implementation with the caching functionality, rather than access data in the EJB tier and cache it in the web container.

In a collocated application, there's no need to perform all data access in the same place. For example, it's legitimate to perform transactional data access from EJBs (to leverage CMT) and non-transactional data access from objects in the web container (because it's simpler and faster). We'll adopt this mixed approach in the sample application.

Data Access in the Web Tier

In contrast, data access in the web tier (the logical architectural layer concerned with presenting a web interface) is a poor design choice. Business objects running in the web container should be distinct from web tier components, will depend on the Servlet API.

Servlets and Web-Specific Classes

There is no justification for performing data access from web-specific classes. There's no reason that data access objects should be tied to the Servlet API. This will prevent their use in an EJB container if required. UI code should also be shielded from data source implementation issues: changing a table or column name in an RDBMS, for example, should never break a web interface. Data access from web-specific classes is unnecessary, as there should be a layer of business objects available to them.

Data Access from JSP Pages

However, there is still one worse option for performing data access. The least attractive data access option in J2EE systems is data access from JSP pages. It tends to lead to problems with error handling and loss of the distinction between business logic, data access and presentation. Yet it is surprisingly widespread, so we can't ignore it.

In the early days of JSP, JSP "Model 1" systems were common. Many developers attempted to replace servlets altogether with JSP pages, partly for the enhanced authoring convenience. JSP pages often contained data access code, along with much of the rest of the application. The results were appalling.

Today there's wide awareness of the value of MVC concepts in Java web applications (we'll discuss this issue in detail in Chapters 12 and 13). However, with the introduction of custom tags in JSP 1.1, welcome though they were in other ways, data access from JSP pages has once more raised its ugly head.

JDBC access from custom tags is superficially appealing, because it's efficient and convenient. Consider the following JSP fragment from the JSP Standard Tag Library 1.0 specification, which transfers an amount from one account to another using two SQL updates. We'll discuss the JSP STL Expression Language in Chapter 13. The ${} syntax is used to access variables already defined on the page:

    <sql:transaction dataSource="${dataSource}">      <sql:update>        UPDATE account        SET Balance = Balance - ?        WHERE accountNo = ?        <sql:param value="${transferAmount}"/>        <sql:param value="${accountFrom} "/>      </sql:update>      <sql:update>        UPDATE account        SET Balance = Balance + ?        WHERE accountNo = ?        <sql:param value="${transferAmount)"/>        <sql:param value="${accountTo}" />      </sql:update>    </sql:transaction> 

Now let's consider some of the design principles such a JSP violates and the problems that it is likely to produce:

  • TheJSP source fails to reflect the structure of the dynamic page it will generate. The 16 lines of code shown above are certain to be the most important part of a JSP that contains them, yet they generate no content.

  • (Distributed applications only) Reduced deployment flexibility. Now that the web tier is dependent on the database, it needs to be able to communicate with the database, not just the EJB tier of the application.

  • Broken error handling. By the time we encounter any errors (such as failure to communicate with the database); we're committed to rendering one particular view. At best we'll end up on a generic error page; at worst, the buffer will have been flushed before the error was encountered, and we'll get a broken page.

  • The need to perform transaction management in a JSP, to ensure that updates occur together or not at all. Transaction management should be the responsibility of middle tier objects.

  • Subversion of the principle that business logic belongs in the middle tier. There's no supporting layer of middle tier objects. There's no way to expose the business logic contained in this page to non-web clients or even web services clients.

  • Inability to perform unit testing, as the JSP exposes no business interface.

  • Tight coupling between page generation and data structure. If an application uses this approach and the database schema changes, many JSP pages are likely to need updating.

  • Confusion of presentation with content. What if we wanted to expose the data this page presents in PDF (a binary format that JSP can't generate)? What if we wanted to convert the data to XML and transform it with an XSLT stylesheet? We'd need to duplicate the data access code. The business functionality encapsulated in the database update is tied to JSP, a particular view strategy.

If there is any place for data access from JSP pages using tag libraries, it is in trivial systems or prototypes (the authors of the JSP standard tag library share this view).

Important 

Never perform data access from JSP pages, even when it is given the apparent respectability of a packaged tag library. JSP pages are view components.



Expert One-on-One J2EE Design and Development
Microsoft Office PowerPoint 2007 On Demand
ISBN: B0085SG5O4
EAN: 2147483647
Year: 2005
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net