Entity Bean Concepts

Entity beans are intended to free session beans from the low-level task of working with persistent data, thus formalizing good design practice. They became a core part of the EJB specification in version 1.1; version 2.0 introduced major entity bean enhancements. EJB 2.1 brings further, incremental, enhancements, which I discuss when they may affect future strategy, although they are unavailable in J2EE 1.3 development.

Entity beans offer an attractive programming model, making it possible to use object concepts to access a relational database. Although entity beans are designed to work with any data store, this is by far the most common case in reality, and the one I'll focus on in this chapter. The entity bean promise is that the nuts and bolts of data access will be handled transparently by the container, leaving application developers to concentrate on implementing business logic. In this vision, container providers are expected to provide highly efficient data access implementations.

Unfortunately, the reality is somewhat different. Entity beans are heavyweight objects and often don't perform adequately. O/R mapping is a complex problem, and entity beans (even in EJB 2.0) fail to address many of its facets. Blithely using object concepts such as the traversal of associations with entity beans may produce disastrous performance. Entity beans don't remove the complexity of data access; they do reduce it, but largely move it into another layer. Entity bean deployment descriptors (both standard J2EE and container-specific) are very complex, and we simply can't afford to ignore many issues of the underlying data store.

There are serious questions about the whole concept of entity beans, which so far haven't been settled reassuringly by experience. Most importantly:

  • Why do entity beans need remote interfaces, when a prime goal of EJB is to gather business logic into session beans? Although EJB 2.0 allows local access to entity beans, the entity bean model and the relatively cumbersome way of obtaining entity bean references reflects the heritage of entity beans as remote objects.

  • If entity beans are accessed by reference, why do they need to be looked up usingJNDI?

  • Why do entity beans need infrastructure to handle transaction delimitation and security? Aren't these business logic issues that can best be handled by session beans?

  • Do entity beans allow us to work with relational databases naturally and efficiently? The entity bean model tends to enforce row-level (rather than set-oriented) access to RDBMS tables. This is not what relational databases are designed to do, and may prove inefficient.

  • Due to their high overhead, EJBs are best used as components, not fine-grained objects. This makes them poorly suited to modeling fine-grained data objects, which is arguably the only cost-effective way to use entity beans. (We'll discuss entity bean granularity in detail shortly.)

  • Is entity bean portability achievable or desirable, as databases behave in different ways? There's real danger in assuming that entity beans allow us to forget about basic persistence issues such as locking.

Alternatives such as JDO avoid many of these problems and much of the complexity that entity beans introduce as a result.

It's important to remember that entity beans are only one choice for data access in J2EE applications. Application design should not be based around the use of entity beans.

Important 

Entity beans are one implementation choice in the EJB tier. Entity beans should not be exposed to clients. The web tier and other EJB clients should never access entity beans directly. They should work only with a layer of session beans implementing the application's business logic. This not only preserves flexibility in the application's design and implementation, but also usually improves performance.

This principal, which underpins the Session Façade pattern, is universally agreed: I can't recall the last time I saw anyone advocate using remote access to entity beans. However, I feel that an additional layer of abstraction is desirable to decouple session beans from entity beans. This is because entity beans are inflexible; they provide an abstraction from the persistence store, but make code that uses it dependent on that somewhat awkward abstraction.

Important 

Session beans should preferably access entity beans only through a persistence façade of ordinary Java data access interfaces. While entity beans impose a particular way of working with data, a standard Java interface does not. This approach not only preserves flexibility, but also future-proofs an application. I have grave doubts about the future of entity beans, as JDO has the potential to provide a simpler, more general and higher-performing solution wherever entity beans are appropriate. By using DAO, we retain the ability to switch to the use of JDO or any other persistence strategy, even after an application has been initially implemented using entity beans.

We'll look at examples of this approach in the next chapter.

Important 

Due to the significant changes in entity beans introduced in EJB 2.0, much advice on using entity beans from the days of EJB 1.1 is outdated, as we'll see.

Definition

Entity beans are a slippery subject, so let's start with some definitions and reflection on entity beans in practice.

The EJB 2.0 specification defines an entity bean as, "a component that represents an object-oriented view of some entities stored in a persistent storage, such as a database, or entities that are implemented by an existing enterprise application". This conveys the aim of entity beans to "objectify" persistent data. However, it doesn't explain why this has to be achieved by EJBs rather than ordinary Java objects.

Core J2EE Patterns describes an entity bean as, "a distributed, shared, transactional and persistent object". This does explain why an entity bean needs to be an EJB, although the EJB 2.0 emphasis on local interfaces has moved the goalposts and rendered the "distributed" characteristic obsolete.

All definitions agree that entity beans are data-access components, and not primarily concerned with business logic.

Another key aim of entity beans is to be independent of the persistence store. The entity bean abstraction can work with any persistent object or service: for example, an RDBMS, an ODBMS, or a legacy system.

I feel that this persistence store independence is overrated in practice:

  • First, the abstraction may prove very expensive. The entity bean abstraction is pretty inflexible, as abstractions go, and dictates how we perform data access, so entity beans may end up working equally inefficiently with any persistence store.

  • Second, I'm not sure that using the same heavyweight abstraction for different persistence stores adds real business value.

  • Third, most enterprises use relational databases, and this isn't likely to change soon (in fact, there's still no clear case that it should change).

In practice, entity beans usually amount to a basic form of O/R mapping (when working with object databases, there is little need for the basic O/R mapping provided by entity beans). Real-world implementations of entity beans tend to provide a view of one row of a relational database table.

Important 

Entity beans are usually a thin layer objectifying a non-object-based data store. If using an object-oriented data store such as an ODBMS, this layer is not needed, as the data store can be accessed using helper classes from session beans.

The EJB specification describes two types of entity beans: entity beans with Container Managed Persistence (CMP), and entity beans with Bean Managed Persistence (BMP). The EJB container handles persistence for entities with CMP, requiring the developer only to implement any logic and define the bean properties to be persisted. In the case of entities with BMP, the developer is responsible for handling persistence, by implementing callback methods invoked by the container.

How Should We Use Entity Beans?

Surprisingly, given that entity beans are a key part of the EJB specification, there is much debate over how to use entity beans, and even what they should model. That this is still true as the EJB specification is in its third version, is an indication that experience with entity beans has done little to settle the underlying issues. No approach to using entity beans has clearly shone in real applications.

There are two major areas of contention: the granularity of entity beans; and whether or not entity beans should perform business logic.

The Granularity Debate

There are two major alternatives for the object granularity entity beans should model: fine-grained and coarse-grained entity beans. If we're working with an RDBMS, a fine-grained entity might map to a row of data in a single table. A coarse-grained entity might model a logical record, which may be spread across multiple tables, such as a User and associated Invoice items.

EJB 2.0 CMP makes it much easier to work with fine-grained entities by adding support for container-managed relationships and introducing entity home methods, which facilitate operation on multiple finegrained entities. The introduction of local interfaces also reduces the overhead of fine-grained entities. None of these optimizations was available in EJB 1.1, which meant that coarse grained entities. were usually the only choice to deliver adequate performance. Floyd Marinescu, the author of EJB Design Patterns, believes that the EJB 2.0 contract justifies deprecating the coarse-grained entity approach.

Coarse-grained Composite Entities are entity beans that offer a single entry point to a network of related dependent objects. Dependent objects are also persistent objects, but cannot exist apart from the composite entity, which controls their lifecycles. In the above example, a User might be modeled as a composite entity, with Invoice and Address as dependent objects. The User composite enlity would create Invoice and Address objects as needed and populate them with the results of data loading operations it manages. In contrast to a fine-grained entity model, dependent objects are not EJBs, but ordinary Java objects.

Coarse-grained entities are arguably more object-oriented than fine-grained entities. They need not slavishly follow the RDBMS schema, meaning that they don't force code using them to work with RDBMS, rather than object, concepts. They reduce the overhead of using entity beans, because not all persistent objects are modeled as EJBs.

The major motivation for the Composite Entity pattern is to eliminate the overhead of remote access to finegrained entities. This problem is largely eliminated by the introduction of local interfaces. Besides the remote access argument (which is no longer relevant), the key arguments in favor of the Composite Entity pattern are:

  • Greater manageability. Using fine-grained entity beans can produce a profusion of classes and interfaces that may bear little relationship to an application's use cases. We will have a minimum of three classes per table (local or remote interface, home interface, and bean class), and possibly four or five (adding a business methods interface and a primary key class). The complexity of the deployment descriptor will also be increased markedly.

  • Avoiding data schema dependency. Fine-grained entity beans risk coupling code that uses them too closely to the underlying database.

Both of these remain strong arguments against using fine-grained entities, even with EJB 2.0.

Several sources discuss composite entity beans in detail (for example, the discussion of the Composite Entity pattern in Core J2EE Patterns) However, Craig Larman provides the most coherent discussion I've seen about how to model coarse-grained entities (which he calls Aggregate Entities). See http://www.craiglarman.com/articles/Aggregate%20Entity%20Bean%20Pattern.htm. Larman suggests the following criteria that distinguish an entity bean from a dependent object:

  • Multiple clients will directly reference the object

  • The object has an independent lifecycle not managed by another object

  • The object needs a unique identity

The first of these criteria can have an important effect on performance. It's essential that dependent objects are of no interest to other entities. Otherwise, concurrent access may be impaired by the EJB container's locking strategy. Unless the third criterion is satisfied, it will be preferable to use a stateless session bean rather than an entity; stateless session beans allow greater flexibility in data access.

The fatal drawback to using the Composite Entity pattern is that implementing coarse-grained entities usually requires BMP. This not only means more work for developers, but there are serious problems with the BMP entity bean contract, which we'll discuss below. We're not talking about simple BMP code, either - we must face some tricky issues:

  • It's unacceptably expensive to materialize all the data in a coarse-grained entity whenever it's accessed. This means that we must implement a lazy loading strategy, in which data is only retrieved when it is required. If we're using BMP, we'll end up writing a lot of code.

  • The implementation of the ejbStore() method needs to be smart enough to avoid issuing all the updates required to persist the entire state of the object, unless the data has changed in all the persistent objects.

Core J2EE Patterns goes into lengthy discussions on the "Lazy Loading Strategy", "Store Optimization (Dirty Marker) Strategy" and "Composite Value Object Strategy" to address these issues, illustrating the implementation complexity the composite entity pattern creates. The complexity involved begins to approach writing an O/R mapping framework for every Composite Entity.

The Composite Entity pattern reflects sound design principles, but the limitations of entity bean BMP don't allow it to work effectively. Essentially, the Composite Entity pattern uses a coarse-grained entity as a persistence façade to take care of persistence logic, while session beans handle business logic. This often worrks better if, instead of an entity bean, the persistence façade is a helper Java class implementing an ordinary interface.

Note 

In early drafts released in mid-to-late 2000, the EJB 2.0 specification appeared to be moving in the direction of coarse-grained entities, formalizing the use of "dependent objects". However, dependent objects remained contentious on the specification committee, and the late introduction of local interfaces showed a complete change of direction. This appears to have settled the entity granularity debate.

Important 

Don't use the Composite Entity pattern. In EJB 2.0 entity beans are best used for relatively fine-grained objects, using CMP.

The Composite Entity pattern can only be implemented using BMP or by adding significant hand-coded persistence logic to CMP beans. Both these approaches reduce maintainability. If the prospective Composite Entity has no natural primary key, persistence is better handled by a helper class from a session bean than through modeling an entity.

The Business Logic Debate

There is also debate about whether entity beans should contain business logic. This is another area in which much EJB 1.1 advice has been rendered obsolete, and even harmful, by the entity bean overhaul in EJB 2.0.

It's generally agreed that one of the purposes of entity beans is to separate business logic from access to persistence storage. However, the overhead of remote calling meant that chatty access to entity beans from session beans in EJB 1.1 performed poorly. One way of avoiding this overhead was to place business logic in entity beans. This is no longer necessary.

There are arguments for placing two types of behavior in entity beans:

  • Validation of input data

  • Processing to ensure data integrity

Personally, I feel that validation code shouldn't go in entity beans. We'll talk more about validation in Chapter 12. Validation often requires business logic, and - in distributed applications - may even need to run on the client to reduce network traffic to and from the EJB container.

Ensuring data integrity is a tricky issue, and there's more of a case for doing some of the work in entity beans. Type conversion is a common requirement. For example, an entity bean might add value by exposing a character column in an RDBMS as a value from a set of constants, While a user's registration status might be represented in the database as one of the character values I, A, or P, an entity bean can ensure that clients see this data and set it as one of the constant values Status. INACTIVE, Statu ACTIVE, or Status. PENDING. However, such low-level data integrity checks must also be done in the database if other processes will update it.

In general, if we distinguish between business logic and persistence logic, it's much easier to determine whether specific behavior should be placed in entity beans. Entity beans are one way of implementing persistence logic, and should have no special privilege to implement business logic.

Important 

Implement only persistence logic, not business logic, in entity beans.

Session Beans as Mediators

There's little debate that clients of the EJB tier should not work with entity beans directly, but should work exclusively with a layer of session beans. This is more an architectural issue than an issue of entity bean design, so we'll examine the reasons for it in the next chapter.

One of the many arguments for using session beans to mediate access to entity beans is to allow session beans to handle transaction management, which is more of a business logic issue than a persistence logic issue. Even with local invocation, if every entity bean getter and setter method runs in its own transaction, data integrity may be compromised and performance will be severely reduced (due to the overhead of establishing and completing a transaction).

Note that entity beans must use CMT. To ensure portability between containers, entity beans using EJB 2.0 CMP should use only the Required, RequiresNew, or Mandatory transaction attributes.

Important 

It's good practice to set the transaction attribute on entity bean business methods to Mandatory in the ejb-jar.xml deployment descriptor. This helps to ensure that entity beans are used correctly, by causing calls without a transaction context to fail with a javax.transaction.TransactionRequiredException. Transaction contexts should be supplied by session beans.



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