What Is an Entity Bean?

   

As you saw in Chapter 3, "EJB Concepts," the EJB specification defines three types of enterprise beans: entity, session, and message-driven beans. As was pointed out there, the specification assigns distinct roles to each of these bean types. This chapter and the three that follow introduce you to the purpose behind entity beans and teach you how to implement and deploy them. Later chapters do the same for session and message-driven beans. The fact that four chapters are dedicated to entity beans should be your first indication that there's plenty to learn about this first type of enterprise bean.

An entity bean represents a persistent object that usually corresponds to a row in a relational database table (or several related rows in multiple tables). Having long-term persistence is what distinguishes entity beans from the other types of EJBs more than anything else. As you'll see in Chapter 9, "Session Beans," a session bean can be stateful but that state is maintained for a relatively short time. Because the data that defines an entity object is stored in a database or provided by some other enterprise system, entity beans have state that persists beyond the lifetime of the processes in which they execute. Short of a catastrophic database failure, entity objects have long- term persistence that is intended to survive even a server crash.

Virtually any enterprise application you develop must interact with information stored in a database. Whether a system supports order entry, access to patients ' medical records, or wireless stock trading from a PDA, persistent data is typically critical to what a business application does. Given this, defining a category of EJB for working with persistent data makes sense. A lot of processing can take place related to retrieving and updating the contents of a database, so the EJB architecture provides a foundation to support it.

It's true that the need for persistent data goes along with using entity beans, but that isn't the sole intent. Multitudes of enterprise applications have been built without the use of entity beans, so there must be more to them than just persistence. What you should be thinking when you design entity beans is that the goal is to create reusable business objects that manage persistent data as part of their responsibilities. Entity beans should represent key business entities that can be reused across an enterprise's applications. Examples of business entities can include objects that represent customers, orders, invoices, medical records, stock trades, and so on.

The responsibilities of the EJB container include the management of concurrent access and transactions so that entity beans can fulfill their role when faced with the demands of multiple clients. When multiple clients access a particular business object that's been implemented using an entity bean, the container enforces serialized access to that object. This means that two clients can't modify the state of such an object at the same time. For example, if you and your business partner maintain a joint bank account, an application that uses an entity bean to represent an account could correctly handle simultaneous requests from both of you to withdraw funds without any special effort by the application programmer. If your request reached the entity instance first (in the form of a method call on the enterprise bean), it would be processed completely before the container would allow any other calls to be made on the bean instance that is representing your account. The concurrency management provided for entity beans supports this type of scenario even without the use of transactions (you'll see much more about the role of transactions in EJB in Chapter 12, "Transactions"). Entity beans aren't always the preferred approach for read-only access to a database, but their support for concurrent access makes them well suited for modifying persistent data.

Another advantage of entity beans relates to instance pooling and scalability. As you'll learn more about later in this chapter, the container maintains a pool of entity instances that are used to support the specific business entities accessed by an application. This pooling provides for efficient sharing of memory while ensuring the integrity of the data associated with your business entities. This built-in scalability is something you wouldn't get if you were to use session beans or regular Java classes to manage entity state.

The rest of this section looks more at the characteristics of an entity bean. One of the first things you need to learn is how to decide whether a particular type of object warrants an entity bean representation. You then need to learn what you have to do as a bean provider to develop an entity bean and the interfaces, classes, and deployment descriptors that support it.

Business Logic

If you've worked with regular JavaBeans, you know that they typically implement GUI widgets or simple data structures. Those that serve as data structures are usually more concerned with exposing properties to the classes that use them than they are with implementing any significant application logic. JavaBeans are primarily client-side and Web tier components , so you wouldn't want them to do any more than this in most cases.

EJBs have some similarity to JavaBeans in that they share the idea of component-based development. That's about as far as the similarity goes, however. EJBs live on the server and are given far more responsibility than their distant cousin, JavaBeans. EJBs are heavyweight components, so they need to offer more than access to a simple set of properties to make their use worthwhile. Primarily, an EJB justifies its existence and the overhead incurred when accessing it through the container by providing business logic to an application.

An entity bean class is usually expected to contain more than its persistent attributes and a list of get and set methods to go with them. Otherwise, it would be hard to justify its reuse across applications. An entity bean typically is expected to do more by providing the business logic related to the data it represents. At a minimum, this can include the validation rules that control how an entity's state can be modified. It's also reasonable to expect an entity bean to define the methods that manipulate its data and aid in its interpretation by the applications that use it. As a developer, it's business logic like this that you want to reuse. As with any good object-oriented design, putting business logic into components that are reused means that the logic is written only once and it can be maintained in one place. As part of this, you must be conscious of the type of business logic that's appropriate for an entity bean. The logic implemented within an entity bean class should, in general, apply only to the data for which the entity is responsible and the relationships it maintains. As you'll see in later chapters, more elaborate workflow or controller logic usually is more appropriately placed in a session bean.

Although most entity beans contain non-trivial business logic, this isn't as strict a guideline as it might seem at first. Because of the persistence mechanisms associated with entity beans and the concurrent access control provided by the container, it sometimes makes sense to implement an entity bean that is significant from a data standpoint but not from a business logic one. The services offered by the EJB container provide a relatively simple way to support manipulation of shared data by multiple users of a system. If this is important to a system you're building, it might be all the justification you need to use entity beans.

Coarse-Grained Objects

Even though entity beans represent persistent objects and provide a number of benefits, you shouldn't automatically implement every persistent class in your application as an entity bean. The services that the EJB container provides to an entity bean are great when you need them, but they don't come for free. Every call to a method exposed through an EJB's remote interface has the potential of being a remote call. Even if an EJB is called by a local client or a remote client EJB running in the same JVM, the container must still intercede and enforce security and manage the transactional needs of the method. The use of an entity bean requires a certain amount of overhead, and that overhead should be justified.

In general, you should limit entity beans to representing the coarse-grained persistent objects in your system. This means that concepts such as a Customer or an Order might be good candidates for entity beans but those such as an Address or an OrderLineItem likely aren't. Objects such as Address and OrderLineItem are better handled by allowing an entity bean to manage them behind a higher-level interface that is presented to clients. This way, a client accessing the details of an order can rely on an Order entity bean to manage its OrderLineItem s instead of the client being expected to have the knowledge necessary to do it directly. Using this approach, the business logic stays inside the entity bean where it belongs, and the entity provides significant behavior that's worthy of reuse.

The overhead of accessing an entity bean is the greatest for remote clients because of the marshalling of arguments and the potential network traffic involved. If you're using EJB 1.1, remote clients are your only option, so limiting entity beans to coarse-grained objects has significant performance advantages. EJB 2.0, however, has changed the playing field somewhat with its support for local clients. If an entity bean supports only local clients, the overhead of remote calls can be avoided. In fact, as will be pointed out as the examples are developed, local client access is the recommended approach for using entity beans. Even with the advantages brought about by local clients, it's still a better idea in most cases to limit your entity beans to coarse-grained objects. This encourages the encapsulation of related business logic. The use of local clients makes it reasonable to perform many fine-grained calls on a coarse-grained entity without suffering a severe performance penalty.

The need to limit remote calls to entity beans in EJB 1.1 led to patterns based on accessing and setting multiple fields of an entity bean in a single call. To learn more about this approach, see "Minimizing Remote Calls," p. 465 .

You can often identify candidate entity beans by looking for the independent objects in your problem domain. These are the objects that exist regardless of the state of any other objects with which they're associated. A Customer object has a unique identity and would likely exist in a system until you decided to remove it directly. On the other hand, an address associated with a customer has no identity of its own and would be of no use if the customer were deleted.

By itself, the independence test might not be enough to justify using an entity bean for a particular type of object. You also must consider whether a class needs the services the container provides to an entity bean. The need for persistence is a minimum requirement for a potential entity bean, but if a class doesn't need any of the concurrency, security, transactional, or other services offered by the container, it's likely that an entity bean isn't a good choice. If you're using EJB 1.1, you especially need to be conscious of the distributed nature of EJB. If a candidate class doesn't need remote exposure to distributed clients, an entity bean implementation isn't appropriate unless you're using EJB 2.0 and plan to limit yourself to local clients.

Representing Dependent Objects

Given that you won't often implement all your persistent classes as entity beans, you have to do something else with the ones that don't make the cut. The objects that you don't implement as entity beans are known as dependent objects.

Note

If you followed the draft versions of the EJB 2.0 Specification, you know that, for a time, formal support for dependent objects and the management of their persistence was proposed. This idea later was dropped in favor of support for local client access to entity beans. The use of "dependent objects" in this book simply refers to persistent objects that aren't represented by entity beans. This term was used in much of the literature on entity beans before the EJB 2.0 Specification was written, and it continues to be used in the same way.


A dependent object is often, but not always, an object that's owned by one of your entity objects. Going back to the customer example, a Customer entity bean in an order entry system would likely have several associated Address objects (maybe one for billing and another for shipping). These addresses are dependents of the Customer and are owned by it. Access to them should be done through the Customer so that they aren't made directly accessible to clients (especially remote ones). This encapsulates the functionality related to these objects and allows them to be accessed and manipulated without incurring the overhead of working through the container. In this example, the Customer should have sole responsibility for creating and deleting its addresses. If a Customer is deleted, its Address objects should be deleted along with it. A dependent object is often one whose life cycle is controlled by some other object. You can think of this as an example of composition. A customer entity can be composed of a Customer object and its Address objects plus any other objects that are necessary to define its persistent state.

There's nothing overly complicated about declaring a class to represent a dependent object. In general, you simply implement a dependent object as a regular Java class (or possibly multiple classes if it's complex enough).

Dependent objects can be relatively simple but that's not always the case. A dependent object can be just as complex as some entity beans. The decision to implement an object using a dependent object instead of an entity bean is based on the life-cycle management for the object and how it needs to be accessed. Nothing requires a dependent object to be free of business logic. You'll even find examples of dependent objects having their own dependent objects that they're responsible for managing.

Each dependent object class can be associated with one or more tables in your database. This build-up of classes and tables is where the coarse-grained aspect of an entity bean is evident. When you consider an entity bean, you must take its dependent objects and everything that they do into account as well. The interface an entity bean presents to its clients can be a facade for a very complex set of associated objects and business logic.

As with anything, tradeoffs are attached to encapsulating functionality within an entity bean using dependent objects. If the idea of making an entity bean coarse-grained gets taken too far, the entity can become so tied to a specific application that it ends up being difficult, if not impossible , to reuse. One way to avoid this problem is to keep the concepts of association and aggregation in mind. If an entity is simply associated with some object, a dependent object representation might be inappropriate. This is true even if it appears that this associated object will be accessed only through the entity. For example, in an order entry system, it might seem like a good idea at first to encapsulate a customer's orders within a Customer entity. The orders are definitely owned by the customer, but to a reporting application that looks at all orders taken by the system, it might be much more efficient to access each order directly. An entity bean is better suited for representing an aggregation of objects than it is for encapsulating associations.

Identifying the Auction Entity Beans

The guidelines covered so far in this section make it possible to take the first step toward mapping the example auction application to an EJB design. Back in Chapter 2, Setting the Stage ”An Example Auction Site, you saw several persistent business objects presented as an initial class design for the example. In particular, EnglishAuction , AuctionOffering , Item , Bid , Bidder , and Address were identified to support the given set of requirements. At that point, no distinction was made as to which of the objects would be implemented as entity beans. Based on the guidelines covered in this section, it's now possible to look at the role of each of these classes and choose an appropriate representation.

EnglishAuction represents the primary object responsible for maintaining the data associated with an auction. This class is the core of the application tier for the auction site, and its implementation will surely include many of the business rules to be enforced within the system. Given all this, it's a straightforward decision to choose an entity bean representation for EnglishAuction . It's also straightforward to conclude that an AuctionOffering associated with an auction is not a coarse-grained, independent business object. The only purpose of this class is to hold a quantity value and link an auction to the item it offers.

The Bid class isn't quite so easy to categorize as some of the others. It does have an identity to some extent, but it's owned by an auction (or possibly a bidder depending on how you choose to look at it) and it's closely tied to the auction business logic. An EnglishAuction should be responsible for accepting bid submissions and creating corresponding Bid objects, so a dependent object representation is the better choice for this class.

Items can be assigned to auctions, but their life cycle isn't determined by an auction. If an EnglishAuction is cancelled and deleted from the system, there's no reason for the Item it was offering for sale to go away with it. The same is obviously true for the auction bidders. An auction is associated with items and bidders, but it's not an aggregation of them. For the auction application, Item and Bidder are independent objects but they don't require much business logic. You could argue that they don't need to be entity beans, but that thought could be shortsighted. If the system were to expand and offer functionality other than auctions, items and bidders (or customers in a more general sense) could quickly take on new requirements.

Table 5.1 summarizes the representation chosen for each of the persistent auction classes.

Table 5.1. Choosing the Auction Entity Beans

Class

Representation

EnglishAuction

Entity bean

AuctionOffering

Dependent object

Bid

Dependent object

Item

Entity bean

Bidder

Entity bean

Address

Dependent object

Bean Provider Responsibilities

As you've seen so far in this chapter, it's important for you to understand the issues to consider when choosing to implement a business object class as an entity bean. After that decision is made, you need to know what to do to actually implement and deploy your entity beans. That's the purpose of the rest of this chapter and the three chapters that follow.

As a bean provider, you're responsible for defining an entity bean class and its dependent objects (if it has any). To make your bean accessible to a client, you also must define its home and component interfaces. Entity beans are unique among EJBs in that they must have an associated primary key class that you're responsible for specifying. This can be as simple as identifying a standard Java class to use, or it can mean declaring a new class to serve that purpose (which isn't that difficult either). The final step in the process is to specify the initial deployment information for your bean.

The biggest choices you have to make as a bean provider for an entity bean relate to the types of clients you support and how the bean's persistence is managed. Under EJB 2.0, an entity bean can support both local and remote clients. However, EJB designers are in rare agreement that entity beans serve their purpose best when they serve other enterprise beans as their only clients. As you'll learn in Chapter 9, session beans function as extensions of their client applications. This bean type is well suited for coordinating the work of one or more entity beans and grouping several calls under a single method exposed to the client. Entity beans, on the other hand, are not intended to function as extensions of the client. An entity bean should encapsulate a set of functionality that is independent of its clients and suitable for reuse across applications. For this reason, entity beans shouldn't be directly exposed to clients outside the application tier. Using EJB 2.0 and session beans deployed in the same container allows you to limit your entity beans to local client use only.

As far as persistence management, you have the option to either write the database access code for an entity bean yourself or define mappings to the database declaratively and let the container interact with the database for you. Each of these approaches has its advantages. Each approach is also complex enough to warrant its own chapter, so you'll learn how to implement your entity bean and dependent object classes in Chapter 6, "Bean-Managed Persistence," and Chapter 7, "Container-Managed Persistence." Container-managed persistence also supports a standard query language for retrieving entity objects that is covered in Chapter 8, "EJB Query Language."

The two persistence approaches for entity beans differ in many ways, but there are plenty of common issues to address regardless of which one you choose. Those issues are what you'll see covered in the rest of this chapter. No matter how you choose to implement an entity bean, you must understand the concepts behind how they're intended to be used. From the practical side, you also need to know how to declare home and component interfaces, specify primary key classes, and define deployment descriptors.



Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

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