Coarse Grained BMP beans with Dependent Value Objects

原创 2001年09月19日 12:40:00
Coarse Grained BMP beans with Dependent Value Objects
is a draft pattern from the upcoming sequel of Mastering Enterprise Java Beans. The pattern describes how to properly implement the equivalent of Dependent Objects in BMP, and provides a fully resuable implementation as an example. The pattern does not describe the motivation for dependent objects, that is a separate pattern and you can learn more about it by reading the EJB 2.0 specs or Sun's ejb-interest archives.
Coarse Grained BMP beans with Dependent Value Objects
By Floyd Marinescu, Senior Architect, The Middleware Company.
Please email comments/suggestions to:

Performance and efficiency concerns require a standard way to build coarse-grained entity beans using BMP as well as CMP.

Dependent objects provide an automatic way to build coarse-grained entity beans for CMP entity beans, but the EJB 2.0 specification doesn’t provide an equivalent mechanism for BMP entity beans.

* * *

Building your entity beans to be coarse-grained is a common performance optimization. It allows modeling the business objects with plain java classes rather than as entity beans, reducing the inter-remote object communication and transactional overhead associated with entity beans.  These plain classes typically have a life cycle dependent on a parent entity bean, do not have a distinct identity of their own and do not need to be referenced remotely by a client. For CMP, these objects are called dependent objects, and EJB 2.0 defines a standard way to define CMP dependent objects, leaving the complex task of persisting them to the underlying application server.

Unfortunately, BMP entity bean developers cannot leverage dependent objects, they are a CMP construct only. However, BMP developers should still be able to create coarse-grained entity beans,


BMP developers should model dependent business data in plain java classes called Dependent Value Objects.  Dependent Value Objects are stored inside your entity beans and are created, modified and removed by your entity beans. Unlike dependent objects with CMP, BMP developers must explicitly write the persistence code of dependent value objects.

Dependent Value Objects are similar to Value Objects in that they are plain java classes and are transportable over the network (this is one advantage over CMP dependent objects, which cannot be accessed by clients). Unlike Value Objects, Dependent Value Objects are persistent objects whose life cycle is managed by an entity bean, whereas Value Objects only exist to transport data across the network in bulk, and are typically discarded once data has been read.

An entity bean can store dependent value objects in a one to one, or one to many fashion.  For example, consider a Resume. A Resume entity bean would only require one Address dependent value object, whereas it would require multiple Job Entry objects, which could be stored in a Collection inside the Resume entity bean, as in figure 1.

Figure 1: ResumeBean class diagram with Address and Job Entry Dependents

Implementing dependent value objects with BMP is not trivial. A good implementation will feature:

  • Dependent value objects that map to tables in a database
  • Immutable dependent value objects
  • Lazy loading of dependent value objects
  • Intelligent lifecycle management  (caching updates until ejbStore, only storing new or modified dependent value objects, etc)
  • Partitioning of persistence logic from business logic

One of the easiest ways to persist dependent value objects is to simply serialize them to a SQL BLOB column in the table which your entity bean maps to. If dealing with a collection of dependent value objects, the whole collection could be serialized into this column. A better alternative is to persist your dependent value objects to separate tables, using JDBC to map your objects in an attribute-per-column manner. Persisting your dependent value objects in this manner will allow them to be accessible to sql searches and allow you to perform reporting and maintenance directly on the database (you can’t do this if they are stored as blobs). From our Resume example, our Resume entity bean maps to a resumes table in the database, whereas our Address dependent value object maps to an addresses table and our Job Entries map to a  jobentries table, as in figure 2. Since our addresses and job entries are dependent value objects, they do not have their own identity outside of their parent Resume entity bean, and thus they do not have their own primary key, instead they are identified by a resumeID column in the addresses and job entries table.

Figure 2: EJB and dependent object DB mapping

Dependent Value Object should be made immutable, that is, they should have no set methods.  In CMP, dependent objects cannot be passed to a client, they can only be accessed internally by an entity bean. One advantage to this restriction is that it ensures that any updating of data in an entity bean is done through the entity bean’s own business methods (encapsulation).  In BMP, we are not faced with this restriction since dependent value objects are just regular java classes. In order to achieve the same benefit in BMP but still have the flexibility of passing our dependent value objects to clients, dependent value objects should be made immutable. This will ensure that the client doesn’t make changes to the value object assuming that his changes will be instantly reflected on the server, thus forcing the client to perform all changes through the entity beans remote interface.

Lazy Loading is a performance enhancement that allows dependent value objects to be loaded on demand. It avoids the wasteful practice of loading up all of an entity beans dependent value objects inside ejbCreate(), particularly if a client isn’t interested in the dependent data.

Lazy Loading is easy to implement. Each of your dependent value objects or collections can have get methods which:

  • Check to see if the internal dependent value object or collection is has been loaded (is null).
  • Calls the database and loads up the requested dependent data if not previously loaded
  • Passes the requested dependent value object (or collection) to the caller.

Once the dependent value object (or collection) has been read from the database, it can be cached inside the entity bean for future calls, as in our getAddress() and getJobs() in our Resume Bean (see downloadable example source at bottom of pattern).

In a BMP scenario, intelligent life cycle management is the programmers responsibility. Unfortunately, this is not trivial, particularly when dealing with a collection of dependent objects. A lot of life cycle management and database synchronization logic must be written to track dependent value objects as they are created, updated, and deleted.  A good BMP implementation will only update the database with dependent objects that have been modified, created or deleted.  It will also allow multiple operations (update, delete, etc) on dependent objects within one transaction and only synchronize the final state of an entity bean’s dependent objects with the database at transaction completion (in ejbStore).

Partitioning of persistence logic from business logic. Given the complexities of life cycle management of dependent value objects, many BMP developers choose to mix their persistence logic with their business logic by adding primary keys or dirty flags to dependent value objects, even interlacing their business logic with code necessary to track the life cycle of dependent value objects. To make programming with dependent value objects in BMP as easy as it in CMP, a developer should not add any special fields to his dependent value objects, nor should persistence logic be mixed in with business logic.

So how can a BMP developer achieve intelligent dependent value object lifecycle management and keep persistence logic separate from business logic? The answer is to abstract these details into a special collection class designed to track the lifecycle of dependent value objects that it is storing.  Figure 3 illustrates a DependentValueSet, a special implementation of the Java 2 Set Collection. Along with supporting the normal operations of a Set (including add, remove, etc), the collection adds several new methods including an update(oldObject, newObject) method that takes two dependent value objects as a parameters, the original object and the newly updated one.  Since dependent value objects (like CMP dependent objects) do not have any identity of their own (no primary key), we require that the original object be passed as a parameter so that our Set will know which object to replace.

Figure 3: The DependentValueSet Class

Using the DependentValueSet allows CMP developers to achieve separation of persistence logic from business logic because business methods need only interact with the normal operations of the Set interface and the extra update method. Dependent Value Objects are also kept clean; they do not need any special attributes added to track their state, as the DependentValueSet handles all of that transparently.

Our DependentValueSet implementation allows for intelligent lifecycle management by tracking which of our dependent objects were created, deleted or modified internally. This is extremely powerful as it allows the user to perform multiple operations on dependent value objects within one transaction, and synchronize the final state of our dependent value objects just once in ejbStore(). For example, the same dependent value object can be updated multiple times, but in ejbStore(), only one database update needs to be performed.

To support database synchronization, our DependentValueSet adds 5 extra methods:

  • addObjectFromDatabase(Object)
  • getObjectsToInsert()
  • getObjectsToDelete()
  • getObjectsToUpdate()
  • databaseHasBeenUpdated()

The addObjectFromDatabase method is meant to be called when dependent value objects are initially loaded from the database. It allows the DependentValueSet to track the objects that were initially in the database. The getObjectToXXX methods allow a BMP developer to query the DependentValueSet to find out which objects should be inserted, deleted, or updated, and write the dependent value object specific SQL code to handle these updates in ejbStore(). Once synchronization is complete, the DependentValueSet should be notified (databaseHasBeenUpdated ) so that it can clear itself up for the next transaction.

From our Resume example, we store our collection of job entries in a DependentValueSet. The entity beans remote interface exposes create, read, update, and remove (CRUD) operations for job entries, each of which delegate to methods on the DependentValueSet called jobentries, which handles all the life cycle tracking of the resumes jobs. At the end of the transaction (in ejbStore() ), we query our DependentValueSet to determine which job entries have been created, removed, or updated, and execute the appropriate SQL accordingly.

Each Resume only requires one Address dependent value object, thus we don’t need the advanced services of our DependetValueSet. Instead, we can manually get and set the object, and simply keep around an isAddresssModifed flag so that ejbStore() will know if our Address has been set in this transaction, and store it in the database if so.

Download the example source code including the full implementation.


在读的一篇文献中关于RDF的描述: As we know, RDF data is a set of triples with the form (subject, property, object)...
  • wxlchinaren
  • wxlchinaren
  • 2010年08月28日 16:18
  • 3019

fine-grained & coarse grained

Fine-grained和Coarse-grained 一般是指远程方法调用的接口的颗粒大小. 比如, 我有一个远程对象, 他有很多属性和对应的getter和setter方法, 如果我们远程调用对象每...
  • qq_32679835
  • qq_32679835
  • 2017年09月16日 11:27
  • 70


PostgreSQL 8.1 中文文档 Prev Fast Backward Chapter 5. 数据定义 Fast Forward Next 5.11....
  • cdnight
  • cdnight
  • 2014年06月05日 11:01
  • 1101

深度学习(十七)基于改进Coarse-to-fine CNN网络的人脸特征点定位

本篇博文主要讲解2013年face++的大牛们提出的改进的DCNN模型《Extensive Facial Landmark Localization with Coarse-to-fine Conv...
  • hjimce
  • hjimce
  • 2015年11月29日 20:39
  • 9237


内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。   JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字...
  • zhoudaxia
  • zhoudaxia
  • 2014年07月05日 14:50
  • 8356

coarse coding

coarse coding
  • cs123951
  • cs123951
  • 2017年09月05日 15:11
  • 335

PostgreSQL中 drop table指令出现ERROR: cannot drop table userinfo because other objects depend on it

PostgreSQL中 drop table指令出现ERROR: cannot drop table userinfo because other objects depend on it。blue...
  • IDOshi201109
  • IDOshi201109
  • 2016年03月15日 20:44
  • 1810

Coarse-to-fine CNN 人脸特征点定位思路

Reference: Erjin Zhou,Haoqiang Fan,Zhimin Cao,Yuning Jiang,Qi Yin. Extensive facial landmark localiz...
  • 2015年04月30日 23:40
  • 5967


最近在学习Spring框架,偶尔看到Thymeleaf这一HTML模板,支持HTML5,性能和编写都很容易,以后就用它替换JSP了,下面是它在Spring中的配置方式: 1.导入依赖的Jar包: ...
  • tianzhihen_star
  • tianzhihen_star
  • 2014年02月21日 14:18
  • 2869

论文阅读(1)--Fine-grained Image Classification by Exploring Bipartite-Graph Labels

这是阅读《Fine-grained Image Classification by Exploring Bipartite-Graph Labels》这篇论文所做的笔记。这篇论文是来自NEC实验室,是...
  • lc013
  • lc013
  • 2016年07月13日 19:53
  • 3123
您举报文章:Coarse Grained BMP beans with Dependent Value Objects