Container Managed Persistence

[ComponentDesignPatterns | CategoryPattern]

Context

Applicability

Problem

Forces

Solution

Separate the aspects of managing persistence issues away from the components themselves. Make the persistence or transience of a component independent from its type (i.e., allow both persistent and transient instances of the same component type).

Participants

Structure

Collaborations

Resulting Context

Consequences

Known Uses

Enterprise Java Beans

The EnterpriseJavaBeans model has ContainerManagedPersistence as one of its core concepts. The key is that you can move an entity bean from one container to another and not care about how the persistence is done. The same entity could per persisted (at different times) in a Db2 container and an OODB container.

Microsoft COM

ActiveX controls have a facility that allows for persistence to be stored and retrieved in a medium that is independent of component implementation. For instance, when an ActiveX control is placed in a Visual Basic form (the form acts as the component's container), custom properties are stored in two places. During design-time, they're stored in an intermediate binary file. When the program is built, this file is compiled into the executable and fed to the control during runtime.

These same ActiveX controls can be put into a web page and displayed in Internet Explorer (the browser acts as the control's container). The control's location, size, and version are specified in an object tag. When the document is loaded into the browser, the component is instantiated and fed is properties, which are stored in the form of parameter tags encapsulated by the object tag.

Object Databases

ContainerManagedPersistence is at the heart of the architecture of most object-oriented databases like GemStone and ObjectStore. Also, many database broker architectures like TopLink take the same approach.

Example

Implementation

Sample Code

Related Patterns

ContainerManagedPersistence is an aspect ContainerIndependence; some containers need persistence, some don't.


Motivation

Consider the following scenario in ComponentBasedDevelopment. A group of programmers sets out to build a new order processing system. They find two sets of components they need to build (roughly "models" and "views") and begin working on coding their components.

They decide that their system will use Java Serialization to persist its Orders. They make this decision because it is simple, and because only one department of only a few people will ever use this system. They go ahead and code the persistence directly into their models, with some supporting code in the application-level "glue" that ties the models and views together.

Then two months after they ship, disaster strikes. Marketing discovers their little application. They want to roll it out onto the web for thousands of customers to use. When the developers review their code they find that they will have to recode over half of the application because of how deeply embedded their persistence code is. How could they have avoided this needless pain?

They could have taken the approach that something is persistent because of WHERE it is, not WHAT it is. That is, they could have created an object that held onto their models and managed their persistence for them. That way, they could have isolated away the dependencies into a separate container component.

As a container may contain many differing components, it makes sense to centralize their persistence management. Moving the responsibility to the container provides a consistency across all components in that container, and eases the burden on the component developers. Publishing the model, like the EnterpriseJavaBeans specification, also allows container developers to provide a cross-industry standard encouraging the use of cross-container entities.


NatPryce:

What is the Solution here? I think that it is:

I'm afraid I don't have the GOF book handy and can't remember where this fits into the format. Please merge it in with the pattern and feel free to add or modify it.


KyleBrown:

The developers violated OnceAndOnlyOnce. The application, even using serialization, "should" have had the persistence centralized because the developers didn't see, or didn't pay attention to, what the code was telling them. Another case of JustGoodFactoring? -- RonJeffries

Yeah, you're right. But then again, one of the key reasons we have design patterns is to teach newbies what JustGoodFactoring is! Remember that that was one of the common complaints about DesignPatterns by some of the OO "old farts"; it "didn't teach them anything new". But that was the idea!


StuartBarker:

The EJB specification also allows ComponentManagedPersistence, although, as pointed out in the example given in the motivations section, this is not always the best of practices. As a component developer, we cannot necessarily guarantee the level of persistence the container will provide, which is why ComponentManagedPersistence becomes more appealing.

KyleBrown:

 True and a difficult conundrum to solve. ComponentManagedPersistence also brings its own problems -- like having a no-source-code component that saves itself in Oracle that we suddenly need to work with DB2. ComponentManagedPersistence has a subtle attraction for developers - but overall I think it's a wrong turn.

StuartBarker:

Agreed. I was almost at the point of considering this an AntiPattern! But in some ways it's needed as a possible alternative to this pattern. If the component developer wishes his component to only be applicable in a certain domain or application framework that has no persistence management then he's likely to go down the route of ComponentManagedPersistence. I certainly don't like it as it flies in the face of component reuse (unless of course they package up the entire persistence store with the component!).


AlistairCockburn:

I plead ignorance... we have had / seen InheritanceManagedPersistence, with a superclass called PersistentObject, which contained the protocol, caught the "save this object" message, etc., as advertised in the OO sales literature. But I can't figure out how ContainerManagedPersistence works. Does each component know that it is a persistent object? If not, how does the "save this object" get to the container? If yes, it does, it still will not know its container, so how does the "save this object" get to the container?

EricMiller:

Here is how I understand ContainerManagedPersistence at least with EJB (more specific, Weblogic). It behaves similar to an object monitor. When a user request enters the container (on way to the bean) the container loads/activates the object, supplying a transaction context specific to the user. The user then has exclusive access to the object for the duration of that call. When the call exits the bean, the container then deactivates/stores the bean. The container uses reflection in conjunction with a bean descriptor file to perform the storage. The descriptor file provides the mapping between bean and storage. A factory (the Home/Finder) provides construction services. I believe that only Entity beans support container managed persistence.


AlistairCockburn:

Found the answer in InheritanceManagedPersistence:

So, the component must know that it is persistent, and what protocol it is obliged to follow for its sort of persistence (persistence to a stream, or persistence to a structure), and also must advertise that, so that the programmer knows which containers s/he is allowed to use with this persistable component. And the container must pass its handle in to the component as needed, because the component does not know the identity of the container. Do I have it right?

KyleBrown:

Sort of, but not entirely. Someone has to know the structure of the persistent object - usually that's the object itself, but it might be a separate helper object (sort of like a BeanInfo?). Take a look at my CrossingChasms papers; the dynamic patterns advocate a ContainerManagedPersistence approach.

MichaelFeathers:

I have to ask.. are you getting at reflection? External agents figure out what your structure is and "persist" you. Persistence does seem to be one of the cross-cutting aspects of software.. The kind of thing you'd like to change in one place, but unfortunately it ends up touching every class in some manner. I've wondered what it would be like to have every object in a system transparently registered with some agent that "persists" it on demand, and neither the classes or the objects would know anything about it. The agent would have complete access to all object internals and use reflection to get at type information. Breaks encapsulation big time, but I suspect that persistence is one of those things that should force us to jump out of the model.


ChrisCleeland:

I've been grappling with the issue of ContainerManagedPersistence vs ComponentManagedPersistence in my current consulting project. In general, the lines in the sand are drawn with OO folks favoring ContainerManagedPersistence and database folks favoring ComponentManagedPersistence. Specifically, we're working with EJB.

Realizing that both sides have valid points, I have begun a question for a pattern or set of patterns that might allow us the best of both worlds, i.e., modeling types to be persisted independent of the persistence code. Thus, we could easily change out the ComponentManagedPersistence code without affecting the actual component. After a quick survey of the usual places, I'm starting to explore a variation of Visitor in order to achieve this. Has anyone considered this and maybe done it?

Been a long time since I've visited WikiWeb, and today I'm glad I came :-)


PhilipEskelin:

Chris,

Cool - glad you're glad. I wonder if a kind of guidance regarding how you blend or choose between ComponentManagedPersistence and ContainerManagedPersistence can be addressed in a higher level pattern that contains these and perhaps a few others.

Something should be written down that helps the developer use ContainerManagedPersistence to store the context, e.g. the definition and location of interfaces and methods used by a bean, and ComponentManagedPersistence to get and set data it should appropriately manage. Here is an example:

You have a Java bean that calls two CORBA methods - one is to retrieve data and display its results, and the other to submit updated data. Then, let's say generating stubs from the IDL wasn't feasible because you would need to recompile the bean every time an interface changes. So you decide to use Dynamic Invocation Interface (DII) and the Interface Repository (IR) to dynamically build your invocations at runtime. And, you wish to archive the bean's state so it can be instantiated later without contacting the IR and rebuilding the method's signature and location.


PeterMaier:

As the Intent tells us, ContainerManagedPersistence should allow us to separate the aspects of managing persistence away from the components themselves. This should allow us to have persistent as well as transient instances of the same type and gives us the freedom to store those instances in different storage mediums (e.g. flat files vs. RDBMS). This is a wonderful goal to achieve.

If we take a closer look at how AlistairCockburn describes a way of how it could be done, we figure out that the goals are not achieved. If we require our components to implement a defined interface that allows them to provide the "content" that should be made persistent, we explicitly give the components themselves responsibility for their persistence (something we want to get away with).

Furthermore implementing just one such interface (something like IPersistStream) does not allow us to use different kind of storage mechanisms and mediums. Consider the following example:

You are building a front office system for derivatives trading. This system handles derivatives trades that need to be made persistent. For demo purposes you want those trades to be made persistent as a binary bit-stream that is written into a file on your local disk.

In the production system each trade should be decomposed and written into the tables of a fully normalized relational database (which is accessed by several 4GL tools and report writers). Because the financial institution runs a big data warehouse (based on XML) where all trades need to be saved, you have to provide yet another persistence mechanism.

All three approaches to persistence would require our components (trades in this example) to implement a separate interface (or do you think that you would be able to break down the trade into the normalized RDBMS from the contents of a stream that has been written using Java serialization?).

This example makes clear that it is not that easy to achieve the goals of ContainerManagedPersistence. The approach we took when building a persistence framework for a global accounting application is to provide a container that manages the persistence of components based on a specification of those components. These specifications may be different for each kind of storage mechanism and medium, as will be the container.

This way the components are not influenced at all by changing persistence mechanics. Providing a general interface for all containers even allows us to keep the application code independent of persistence issues. What needs to be changed are the specs as well as the container implementation.

The question that comes up is how those specs could look like and how they depend on the components. This is largely driven by the question if you are willing to break encapsulation or not (i.e., allow the container using the spec to access the attributes of the components directly or not). We opted to use some intermediate approach where components need to provide a getter-method for each persistent attribute.


How about PackagedPersistence? In any language there exists a finite number of primitive data types (plus object references). Each persistence media (serial file, random access file, ORB, serial network connection, RDBMS, OODB, etc.) uses a packaging object that is a mediator between the object and the medium by taking the field, type and value information given by the object and packing them in a way which is friendly to the persistence medium.

PackagedPersistence contains the implementation penalties of ComponentManagedPersistence, but can be made more robust in the face of changes in the implementation of the objects being persisted and since it uses a limited interface which makes no assumptions about how a particular primitive is stored in the medium, it can support a much wider variety of persistence media. It also does not rely on any reflection mechanisms, which are not available in every language and which are not robust in the face of changes to the object's implementation anyway.


PhilipEskelin:

Since CBD is more about packaging (where interface is separated from implementation yadda yadda) using InheritanceManagedPersistence isn't applicable at the component (binary) level. However, in the component's implementation, nothing stops you from doing it.

The drawback to it, to ComponentManagedPersistence, and to perhaps PackagedPersistence is that your dependencies and/or persistence requirements are hidden from the users of your component. To get around this, in my current project, I use ThirdPartyBinding with ComponentManagedPersistence by using an external "management" component to handle persistence of component metadata and other administrative functions.

So this is an example of ContainerManagedPersistence where the container delegates management to a separate standard management component coupled by design to one or more of the other components.

Thoughts? I can provide a concrete example if you'd like ;-)


AlexCruise:

In EnterpriseJavaBeans (especially in v2.0), CMP is pretty elegant. Entities don't need to subclass an all-knowing PersistentObject class, nor do they need to be aware of how to persist themselves in any way. Instead, an entity class only has to make public the fields (in EJB 1.x) or accessor/mutator methods (EJB 2.x) that must be persistent, and declare them in the bean's EjbDeploymentDescriptor?. The EjbContainer can do whatever it wants with this information, but most will either hand the deployment descriptor off to a reflection-based persistence interrogator, or generate some code that does the job more quickly. Either way, the actual interface between the public fields-or-methods and the PersistenceMechanism is up to the container vendor. This is a good use for ObjectRelationalMapping techniques.

More info:

http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Entity4.html

--

LuxSpes

Of course, by now everybody knows that EnterpriseJavaBeans (especially in v2.0) is considered a failure. PojoPersistence? has killed ContainerManagedPersistence, and even EnterpriseJavaBeans 3.0 has switched to PojoPersistence? (with some help from AnnotationMetadata).


CategoryPersistence


EditText of this page (last edited December 30, 2008) or FindPage with title or text search