Theory Center

The Theory Center, Inc.               Phone (888) Theory1

1 Winthrop Square                     

Boston, MA 02110                      

Bean Managed Persistence

Deploying eBusiness Smart ™ Components   with Enterprise Data Sources.

 


 

 

 

 

 

 

“To bean, or not to bean…that is the question.”         

- Billy Buybeans, EJB developer and Shakespearian actor


Chapter

 

1

Bean Managed Persistence

Overview

eBusiness Smart Components and Enterprise Data Sources

Theory Center features persistence of Enterprise Java Beans to legacy data sources.   The Enterprise Java Beans are modeled using the Unified Modeling Language.  Java source code is created with the SmartGenerator™ using an additional database mapping specification.  The resulting source code consists of:

n        Files containing Java interfaces, business logic, and other core EJB code.

n        Files containing JDBC instructions to persist Entity Beans using a specified database map.

For detailed instructions on Theory Center’s modeling process and the components in Theory Center’s foundation package, see the document “Modeling with eBSC’s”, published by Theory Center.

The core EJB source code is independent of the persistence method, whether it is container-managed or any implementation of bean-managed persistence.

The source code with JDBC instructions to persist Entity Beans is generated according to one of Theory Center’s reference implementations of bean-managed persistence.  If the user is able to use Theory Center’s reference data model, then this source code may be used as generated.  As is more likely the case, the JDBC source code may be used as templates to persist Enterprise Java Beans to a legacy data model.

One of the advantages of Theory Center’s approach is that business logic and other core EJB source code is independent of the persistence implementation.  This isolates business application development from database development and schema changes.

Document Organization

n        Chapter 2, Considerations in Bean Managed Persistence, provides an overview of the design and implementation process for bean-managed persistence.

n        Appendix 1, Oracle 8.0 Reference Implementation, describes Theory Center’s reference implementation of BMP in a relational database.

n        Appendix 2, Oracle 8.1 Reference Implementation, describes Theory Center’s reference implementation of BMP in an object-relational database.

 

 


Chapter

 

2

Considerations in Bean-Managed Persistence

An Overview of the Design and Implementation of BMP

Container vs. Bean-Managed Persistence

In Container-Managed Persistence, the developer uses the deployment descriptor to tell the container which attributes of the entity bean to persist.  Flexibility is therefore governed by third parties, i.e. the vendors of the container and database.

Bean-Managed persistence gives the developer explicit control of the management of a bean instance’s state.  Advantages to Bean-Managed persistence may include:

n        performance advantages

n        the ability to express complex relationships among data

n        an interface to complex legacy SQL databases via JDBC

n        an interface to other enterprise data sources for example  CICS, MQ-Series

Some disadvantages to bean-managed persistence include:

n        the developer must explicitly code the ejbCreate() ejbLoad(), and other ejb callback methods

n        the developer must explicitly code the finders methods in the home implementation

n        the developer must understand, develop, and maintain a map between bean and database

n        risk of “marrying” a bean’s abstract business logic to a specific database type and structure.

Considerations when Persisting an Enterprise Java Bean

The data model and access mechanisms have a strong impact on persistence logic.  In particular, an Entity Bean’s primary key, attributes, and contained classes must be considered.  Particular attention should be given to other Entity Beans that are contained by value or reference.

The principles discussed in this paper use a framework of mapping EJB Objects to a relational data model using JDBC.  These principles may be generalized by the reader and applied to other mechanisms for modeling and accessing enterprise data.

Complexity of the Mapping Implementation

The reader should consider the factors driving the map between EJB Objects and data storage.

A fixed database schema and a fixed object model may increase the complexity of the mapping implementation.  Flexibility in either the database schema or the object model may correspondingly decrease this complexity.

Serializing objects or parts of objects may help decrease complexity of data mapping.  The tradeoff is that the serialized data is “opaque” and is not easily accessed through third party tools such as report writers.

Dissecting and Persisting an Enterprise Java Bean

Primary Key

The Enterprise Java Beans Specification requires that each Entity Bean has a class that represent attributes that uniquely identify an instance of that bean.  The implication is that these attributes are used in primary key columns or foreign key columns in a relational database.  These attributes cannot be serialized because they must be queried against.

Singleton Attributes

Attributes that have a 1:1 relationship with their class are easily mapped to columns or sets of columns in a relation that characterizes the bean.

Primitive Data Types

Attributes that correspond to JDBC primitive types (e.g. java.sql.Types.LONGVARCHAR, java.sql.types.INTEGER) easily map to columns in a relational table.  If these attributes are serialized they cannot be easily be used in SQL reports or queries.  Serialization of these attributes may impact the complexity or performance of the object-relational map.  References to primitive data types are possible but discouraged.

Compound Data Types

Attributes that are java objects (not EJB’s) are easily decomposed into columns that correspond to the JDBC primitive types.  When these attributes are contained by value they can go in the table (or relation) where the EJB object is persisted.  Care must be taken to ensure they are deleted from the database when the containing EJB object is deleted.

A reference to an attribute can be established with a foreign key to a relation that stores the actual attribute.  It is up to the application designers to determine application specific standards for creating and maintaining these keys. Application logic must ensure dangling references do not occur when the contained object is removed. 

Designers should also consider if the referenced data should have a foreign key back to the containing EJB.  The complexity of this issue increases if many EJBs can reference the data.

Entity Beans

Entity Beans can contain other Entity Beans by value or reference.  The fields in an entity bean’s primary key class comprise a foreign key in the containing bean’s relation.  In addition, the containing bean needs access to the contained bean’s primary key class and home class.  This allows the containing bean to call findByPrimaryKey() to locate the contained bean.

Entity beans should be stored in their own relation, regardless of their containment by value or reference.  Application logic must be developed so beans contained by value are not orphaned, and to avoid dangling references to beans contained by reference.    Designers should also consider if the target entity bean should have a foreign key back to the containing EJB.  The complexity of this issue increases if many EJB’s can reference the data.

Collections: Attributes Contained in a Many-to-One Relationship

Entity beans can contain other Java objects in many-to-one relationship.  These collections can be stored in a separate table or a nested table if the DBMS supports this.  The separate table needs a foreign key to join with the containing entity bean.

Application logic needs to address issues raised by Java’s different collection classes.  Many of these classes do not have a key to access the data.  Some of these classes support ordering which must the persistence logic must manage. 

Performance issues arise when persisting collections that have no primary key.  When one member of the collection changes, the entire collection must be deleted and updated into persistent storage.

The CRUD operations (create, refresh, update, delete) must be done atomically on all the changing attributes of an Entity bean.  This raises issues of transactional integrity and increased resources to support large transactions e.g. transaction logs, open cursors.

Collections can be serialized into a single column if the Java collection class implements the java.io.Serializable interface and the DBMS supports binary data types.  This may simplify the persistence logic.  In this case, whenever any member of the collection changes, the entire collection must be deleted and updated in the database.

Application logic needs to address orphan and dangling reference issues for objects contained by value and reference.  Serialization of collections contained by reference will increase application logic complexity.

Primitive Data Types

Collections of primitive data types raise few issues that have not been previously discussed. Collections of primitive data types by reference are an absurdity, because the only key can be the value of each element in the collection.

Compound Data Types

Collections of compound data types that are contained by value can be serialized or stored in a separate table from the Entity Bean.  If they are stored in a separate table, they need a foreign key to join with the containing entity bean.

Collections of compound data types by reference are possible if there is some unique key that identifies each element in the collection.  The collection of keys would be serialized or stored in a separate table from the containing Entity Bean.  If the keys are stored in a separate table, this table also needs a foreign key to the containing Entity Bean(s).  This makes it possible to avoid dangling references when the object is deleted.

The complexity of the object-relational mapping increases when the objects in a collection have collections themselves.  Many joins may be required to update and refresh the data.  Serialization may reduce this complexity.

 

Entity Beans

Collections of Entity Beans are simplified because of requirement that each Entity Bean have a primary key class.  The collection of primary keys needs to be persisted in serialized or table form. 

As previously stated, Entity Beans should be stored in their own relation.  The containing class needs to have access to the contained bean’s home class and primary key class to invoke findByPrimaryKey() to locate the contained bean.

When entity beans are contained by value, and persisted in a table, this table may not need a foreign key to the containing bean.  When they are contained by reference, the table should have a foreign key to the containing Entity Bean(s).  This makes it possible to avoid dangling references when the contained entity bean

 

 

 

JumpStart™ Bean Managed Persistence

It is possible to map e-Business Smart™ Components to any database available through JDBC.  Theory Center provides two reference implementations of Bean-Managed persistence.  These are available as deployment options in the JumpStart release.

The example Oracle deployment set allows you to map the BuyBeans.com components to Oracle 8.0.5 and above using Theory Center’s Bean-Managed persistence.

The Oracle 8.1.5 Reference Implementation uses serialization to persist most of the attributes of Enterprise Java Beans.  Theory Center’s SmartGenerator has basic object/relational mapping features that generate up to 100% of the mapping from beans to a relational model using serialization.  For complex databases the generated code serves as a starting point for reliable and scalable Bean-Managed Persistence that you can modify and fine-tune.

The Oracle 8.1.5 Reference Implementation uses Oracle’s object-relational features including database object types and nested tables. eBusiness Smart™ Components are stored with a maximum transparency.  It is possible to query on every field in the example BuyBeans object model.  This reference implementation is made available to help illustrate the effort and complexity of more detailed object-relational persistence. 

 

 


Appendix

 

1

Oracle 8.0.5 Reference Implementation

BMP in a Relational Database

Introduction

BMP code for Theory Center Enterprise Beans is generated by the SmartGenerator. The generated BMP code contains JDBC code to INSERT, DELETE, UPDATE and SELECT objects from Relational Database Tables.

 

Given an Entity Bean named “Account”, the generated BMP Java code is stored in the Java source file “AccountTcBmp.java”.

 

The decision on whether an Entity Bean is persisted using CMP or BMP is made at run-time based on environment properties in the Bean Deployment Descriptor properties. The following environment properties are used :

 

PersistenceType

Either BMP or CMP.

PersistenceTcBmpClass

Fully qualified class name of the Beans’s TcBmp class.

PersistenceDbConnClass

Fully qualified class name of the Database Connection class.

PersistenceURL

Database connection pool  resource string.

.          

As an example, the AccountBean has the following entries in its Weblogic Deployment Descriptor File.

 

"PersistenceURL"              

"jdbc:weblogic:jts:bmpPool"

"PersistenceType"

"BMP"

"PersistenceTcBmpClass"

"theory.smart.axiom.accounting.AccountTcBmp"

"PersistenceDbConnClass"

"theory.smart.util.WeblogicDatabaseConnection"

 

If the above environment properties are missing or not set, the AccountImpl class assumes that it is using CMP !! This allows us to keep CMP the default in case these entries were not generated. These settings must be verified during deployment. Errors in specifying these settings result in Null Pointer Exceptions being thrown in ejbCreate(), ejbLoad(), ejbStore(), ejbRemove() methods.

 

How it Works

Generated code for the ejbCreate() method in the AccountImpl class looks like this :

 

public theory.smart.axiom.accounting.AccountPk ejbCreate(theory.smart.axiom.accounting.AccountPk accountPk) throws CreateException, RemoteException

{

  boolean cmp = true;

  try {

                  Properties env = ctx.getEnvironment();

                  String persistenceType = env.getProperty("PersistenceType");

                  if (persistenceType != null && persistenceType.equalsIgnoreCase("BMP")) {

                        cmp = false;

                                String persistenceTcBmp = env.getProperty("PersistenceTcBmpClass");1

                                String persistenceDbConn = env.getProperty("PersistenceDbConnClass");2

                                DatabaseConnection dbConn = (DatabaseConnection) Class.forName(persistenceDbConn).newInstance();

                                dbConn.setContext(ctx);

                                TcBmp tcBmp = (TcBmp) Class.forName(persistenceTcBmp).newInstance();

                                tcBmp.setDatabaseConnection(dbConn);

                                tcBmp.create(accountPk, this);

                  } else {

            super.ejbCreate((SmartKey) accountPk);

                  }

  } catch (java.lang.Exception e) {

                throw new javax.ejb.CreateException (e.getMessage());

  }

 

  ejbCreateInitVars(accountPk);

 

//$EjbCreate$_Begin ------------ CUSTOM CODE ---------------

// Add custom code here

//$EjbCreate$_End   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

if (cmp)

  return null;

else

  return accountPk;

}

 

In the ejbCreate() method, the Bean looks up its environment properties to determine if it was deployed using BMP or CMP. In our example, let us assume it was deployed using BMP. It proceeds to obtain the TcBmp class1 and Database Connection class2 and creates instances of both. After associating the TcBmp class with the Database Connection class, it executes the create() method on the TcBmp file. If the create is successful, it returns the Primary key object [BMP].

How *TcBmp Java class Code is Generated – ormap.properties

BMP Code generation maps Objects to Tables and Object attributes to Table Columns. The data that specifies the Object to Relational data mapping is referred to as the O/R mapping table. The First version of the BMP code generator supports a simple property file syntax. Each entry in the property file is either a Class/Table mapping or an Attribute/Column mapping. The example below shows the mapping for the Order object :

Order=TORDER

Order.key=ORDER_KEY

Order.customer.identifier=CUSTOMER_KEY

 

Line 1 indicates the Order class is mapped to the TORDER Table.

Line 2 indicates the Order class attribute “key” is mapped to the ORDER_KEY column.

Some Objects may contain SmartHandle attributes. When SmartHandles are stored in the table, the attribute must be fully qualified. Line 3 shows how the Customer SmartHandle is stored in the Order Table. Note how the “customer. Identifier” attribute is fully qualified relative to Order since it is stored as a SmartHandle contained in the Order object.

Specifying the O/R mapping file.

 The Smart Generator reads the O/R mapping file when it is invoked with the –ormap flag. For example, if the O/R mapping is stored in the file ormap.properties, add the following command line option :

            -ormap ormap.properties

In the event a property file is not found, the Smart Generator assumes a default mapping of Objects and Attributes – An Object X maps to Table X and Attribute Y maps to column Y.

 


Appendix

 

2

Oracle 8.1.5 Reference Implementation

BMP in an Object-Relational Database

Introduction

The Oracle 8.1.5 Reference Implementation uses Oracle’s object-relational features including database object types and nested tables. eBusiness Smart™ Components are stored with a maximum transparency.  It is possible to query on every field in the example BuyBeans object model.  This reference implementation is made available to help illustrate the effort and complexity of more detailed object-relational persistence. 

Database Schema

See the document “Modeling with eBusinessSmart™ Components published by Theory Center for detailed descriptions of the data types discussed in this section.

Belongings

There are four database types for each eBusinessSmart™ Component Belonging.  These are:

1.       A type that describes the belonging

2.       A type that describes the belonging and adds an additional field that allows a string key to be persisted with the belonging.  This is used to persist objects contained using java.util.TreeMap container.  A limitation is that the primary key is a single string.  An alternative is to serialize an instance of java.lang.Comparable.  This would make the key impossible to use in SQL queries.

3.       A type that corresponds to a nested table of belongings.  This enables collections as nested tables in the table that represents the containing Entity Bean

4.       A type that corresponds to a nested table of belongings with the primary key.  This enables collections of java.util.TreeMap as nested tables in the table that represents the containing Entity Bean.

Primary Keys

There is one database type for each PrimaryKey type.  (There is a PrimaryKey type for each eBusinessSmart™ Component Entity and Configurable Entity.)  Each Primary Key type has:

n        An embedded SmartHandle type, which persists the primary key class name,  home class name, and home name of the Entity Bean,

n        One field for each field in the primary key.  Each of these fields is a primitive data type.

Entity Beans

There is one table for each eBusiness Smart Component Entity and Configurable Entity.  Each table consists of columns for singleton attributes as follows:

n        One column for each attribute in the primary key

n        One  column for each attribute that is a primitive data type.

n        One column for each Belonging.  Fields in the Belonging are dereferenced using the column name and field name in the database data type.

n        One column for the PrimaryKey of an attribute that is an Entity Bean.  Fields in the PrimaryKey including the SmartHandle are dereferenced using the column name and field name  in the database data type.

Each collection in the Entity Bean is represented by a nested table.

Database Operations

The database operations apply to the entity beans.  The four CRUD operations are implemented, plus findByPrimaryKey() and exists(). 

Create

During the Create operation, each primary key field is inserted into the table.  In addition, the fields of each column that is a database type are initialized with null values.  The nested tables are initialized with a single row with each field in each column initialized to null values.

Refresh

In the Refresh operation, the database fields and collections are populated into the bean.

For contained entity beans, the PrimaryKeys are reconstituted from singleton fields or collections, the SmartHandle is recreated using the primary key class name, home class name, and home name that were stored during the update() method.

Update

In the Update operation, the attributes and collections are populated into the database.

The contents of all nested tables are deleted from the database and repopulated from the Entity Bean.  An improvement to this would be to make use of the key in java.util.TreeMap collections.

For contained entity beans, the PrimaryKeys are broken out into individual fields and key class name, home class name, and home name before being stored in the database.

Delete, FindByPrimaryKey, and Exists()

The Delete, FindByPrimaryKey, and Exists operations are simple operations that execute queries or updates using the primary key fields of the entity bean.