How do you abstract data access code that you write from the underlying data store in which it is persisted so that is portable if you choose to change platforms? That question has been long been on the minds of developers developing n-tier applications. Although the J2EE camp has a solution referred to as entity beans, developers on the Microsoft platform have typically had to rely on their own custom class libraries to see them through. Now, however, things may be about to change.
In this article and the one that follows, I'm going to give you an overview of a new technology that Microsoft is working on for release in the next version of the .NET Framework, tentatively dubbed Microsoft ObjectSpaces. The code and concepts discussed in this article are based on a technical preview released at the PDC in October 2001 that Microsoft is using in part to get feedback on the general architecture employed. As a result, much may change as this architecture is refined and improved.
A Little History
Since the mid-1990s, there has been a growing consensus in the IT industry that one key to increasing the scalability of enterprise systems is to implement component-oriented middleware products that provide a hosting environment and also a set of services such as interception, transaction management, object pooling, and threading for middle-tier components that implement business process and data access logic. Having the logic owned by the server in this way allows the server to distribute resources such as database connections more efficiently, rather than allowing each client to own a private set of resources.
Microsoft was the first to exploit this architecture, with the introduction of Microsoft Transaction Server (MTS) in 1996. MTS hosts components based on the Component Object Model (COM) specification and provides life cycle management and distributed transactions in the Windows environment. Microsoft has since enhanced this offering with Component Services (COM+ 1.0) in Windows 2000, which adds new services such as events and queued components. More recently, Microsoft has extended COM+ to be accessible via managed code written in .NET. Enhancements to COM+ will also be rolled out in the upcoming release of Windows .NET Server in the first half of 2002. (See my article here on InformIT for more information.)
Not to be left behind, Sun moved to provide a specification that became Java 2 Enterprise Edition (J2EE, now in its 1.3 release), which vendors could implement to create enterprise applications. The core of J2EE is the Enterprise Java Beans (EJB) specification, detailing the programming model for components that run in component-oriented middleware provided by vendors such as IBM (Websphere), BEA (WebLogic), and other vendors implementing the J2EE specification.
Both the Microsoft and J2EE offerings support the concept of interactions with stateless components that are managed by the middleware layer. In COM+, this is done declaratively by marking a component with the Just-In-Time Activation (JITA) attribute. The COM+ infrastructure then activates and deactivates components with each method call by either actually creating and deallocating an instance of the component or pulling an instance from a pool. In .NET, a component can access COM+ services by deriving from the System.EnterpriseServices.ServicedComponent class.
In J2EE, this model is implemented by building stateless session beans that implement the javax.ejb.SessionBean interface and that the container activates and passivates either through creating and deallocating instances of the class or by pulling them from a pool managed by the container. An XML deployment descriptor can be used to declaratively mark which services of the container the bean should use.
However, that is where the similarity ends. The EJB specification also includes the concept of entity beans. Simply put, entity beans provide an object-oriented interface to allow developers to access data (typically entity type data such as a customer, order, or product) as objects rather than as rows in a database by hiding the persistence work from the client. Entity beans also come in two flavors that support different methods of persistence:
Container-managed persistence (CMP) means that the container in which the bean runs automatically manages the communication with the underlying data store. Different vendors support various levels of complexity using graphical tools to map the methods of a remote interface to tables and columns in the data store. This mapping is performed when the bean is deployed in the container.
Bean-managed persistence (BMP) means that the developer writes custom code in predefined methods in the bean class to manually manage the storage and retrieval of data for the bean, typically using the JDBC APIs. These methods, such as ejbCreate, ejbLoad, ejbStore, and ejbRemove, are called by the container as the bean is manipulated by the client and are used to specify how the data is synchronized with the bean instance.
As we'll discuss shortly, ObjectSpaces includes concepts that map to both CMP and BMP. It also provides some additional features.