본문 바로가기

Dev.../웹서비스

CMP 선택.... 과연?

EJB

Why Choose A CMP Architecture? Find Strengths in Performance


By Tyler Jewell

Last month, I talked about the power of CMP entity EJBs and provided a number of scenarios where leveraging the CMP model would be preferable to developing stateless session EJBs that use JDBC or JDO.

This month, I'll talk about the reasons for using a CMP architecture over a BMP one in entity EJBs.

Reasons to Use BMP with Entity EJBs
First, let's talk about the scenarios where BMP is appropriate for use in an entity EJB system. The biggest reason to use BMP over CMP is because what you want to accomplish cannot be done through BMP:

  • Fields are accessed through stored procedures: If you work in an enterprise that regulates data access through stored procedures, a CMP engine won't know how to interact with the appropriate stored procedures. The entity EJB life cycle is very strict and it's likely that any stored procedure access to a database doesn't follow this life cycle. Also, even if the stored procedures followed the entity EJB life cycle, there would be no standard way of telling a CMP container which stored procedures to invoke during different points in the lifecycle.
  • Persistent store is accessed through alternative methods: WebLogic Server's CMP engine requires the use of a JDBC driver to access the persistent store. If you want to use an alternative access technique such as JDO or a J2EE CA adapter, you need to use a BMP model.
  • The bean's model requires data from multiple stores: WebLogic Server's CMP engine can only pull data from a single table. WebLogic Server 7.0 will support multi-table CMP access, but what do you do if the data in your bean model is from multiple databases? Although there are a number of significant performance reasons for not having a single entity EJB represent data from multiple stores, there are some scenarios where it's a requirement (especially when you try to integrate a legacy system with a new implementation). For these scenarios, a BMP bean should be used.
  • The database requires nonstandard SQL: Databases differentiate themselves by adding proprietary extensions that enable better performance and robust functionality. For example, most databases offer a technique for doing automatic primary key generation; others offer specialized ways of doing optimistic locking at the database level. To take advantage of these features, the SQL submitted to a database usually has to be customized with proprietary extensions defined by the database vendor. CMP engines can differentiate themselves by supporting a wide range of these custom extensions. WebLogic Server 6.1 supports most primary key generation techniques and Oracle's serializable SQL extensions, but if your database requires further optimized SQL, you may need to use a BMP instead.

Why CMP?
BMP entity EJBs won't perform very well. If you're using a BMP EJB, chances are your scenario matches one of the oddball cases listed above. If you choose to use a BMP entity EJB when a CMP engine or a stateless session EJB with JDBC could be used, you're taking an unnecessary performance hit. A BMP entity EJB doesn't come without the overhead of container management, server management, and (sometimes) unnecessary life cycle migration. The purpose of using a BMP is:

  1. To take advantage of representing persistent data in a business object model in your system
  2. To leverage the EJB deployment model, allowing for behavioral changes to be made by modifying XML, not code
  3. Your data access falls into one of the scenarios listed in the first section.

But, if what you're trying to accomplish doesn't fit into one of these scenarios, and it is possible for a CMP container engine to functionally accomplish the data access you require, you should definitely be using CMP. There are a number of concrete reasons for using CMP:

  • BMP entity EJBs can't take advantage of in-server locking models: These include pessimistic and optimistic in-server locking models. There are very few containers that support an in-server optimistic locking model, and it can be very powerful. Optimistic locking delays attempts to lock the underlying data in a database until the transaction begins the commit process. This is difficult to implement because the container needs to be intelligent and aware of any data modifications from the time the transaction started and the time the container places a lock on the data. If the data was modified in that time span by another process, this is called a collision, and the container needs to resolve it by rolling back the transaction or overwriting the data. Containers that support optimistic locking provide a more scalable implementation because data will be locked less frequently and the application server won't spend as many cycles blocking access to locked data.

    By having a container supporting pessimistic and optimistic locking models, a bean developer is freed from dealing with multi-request transactional issues, collision handling, and specialized SQL needed to make these locking scenarios occur. BMP entity EJBs cannot have a container implement these policies since it requires interaction with the underlying persistent store.

  • BMP entity EJBs do not have EJB-QL support: EJB-QL is used to define find() methods and ejbSelect() methods. It allows a developer to quickly configure the way an entity EJB behaves without developing complicated JDBC or SQL code. Vendors, including WebLogic, may add enhancements to EJB-QL to allow developers to continually create more complicated queries. By dong this, the need for using optimized stored procedures diminishes and business logic moves further into the application server tier (which is where it belongs). Additionally, EJB-QL reduces the amount of code in an entity EJB, making it more maintainable, easier to support, and quicker to develop. BMP entity EJBs require find() methods to be implemented manually and, for the reasons listed above, should be avoided.

  • BMP entity EJBs do not have any support for relationships: Your data has relationships with other data. It's a fact of life. If your data has relationships, then your object models in memory will also have relationships. Implementing relationships manually is very challenging. They can be directional and have multiplicity constraints applied to them. Also, many systems don't perform optimally because of the poor implementation of relationships. For example, if you have a one-to-many relationship of objects that are persistently stored, you might implement an aggressive loading model that brings a parent and all of its children into memory every time the parent is accessed. If the parent has 10,000 children, but those children objects are not needed on a regular basis, the system is being burdened with activities that could otherwise be avoided.

    BMP entity EJB containers cannot support relationships because a container needs access to the underlying relationship management technology being used in the persistent store. In the case of relational databases, a container would need to access the primary and foreign key columns to properly manage the relationship. Using BMP, all persistent store access is managed by the bean itself, so the bean needs to manage the relationship manually. Since BMP relationships are nonstandard and very difficult to implement, you run the risk of building a poor-performing system. Also, WebLogic Server's CMP implementation provides aggressive and lazy loading of relationships that would be nearly impossible to implement using BMP.

  • BMP cannot avoid the n+1 problem: One of the problems that plagued CMP engines with EJB 1.1 was the n+1 problem. This was caused by containers that required n+1 database queries and network invocations to load entity EJBs in a parent-child relationship. For example, if you had an Order entity EJB with 1,000 LineItem children entity EJBs in a one-to-many relationship, EJB 1.1 CMP engines would require 1,001 database queries to load all of the EJBs. This is crazy, since it's likely that all of the data was stored in only two tables.

    EJB 2.0 solved this problem for CMP engines by requiring entity EJBs in a relationship to use local interfaces. The container could be guaranteed that entity EJBs in a relationship were going to exist in the same virtual machine, and if a vendor required relationships to be in the same database, the CMP engine could continually optimize the n+1 scenario to be a 1+1 database hit scenario. This isn't the case for BMP containers. Since the container does not create the query, there is no way to "aggregate" all of the information in a standard way to pull in all of the child data all at once. The BMP engine will always have to iterate each of the children, forcing the n+1 problem to remain. One reason for using BMP in a relationship, however, is if you need a relationship that operates over remote interfaces. If the local interface restriction cannot be adhered to, using BMP may be an option.

  • BMP cannot do cascading deletes: For EJBs in a relationship, a CMP container can perform a cascading delete. This means that if a parent object is destroyed, the child objects in the relationship are automatically destroyed as well. Cascading deletes can be done by manually deleting each EJB one at a time or by using specialized database referential integrity mechanisms that automatically delete all of the data reachable through foreign keys when a row is deleted. The latter is almost always preferred for performance reasons.

    Since BMP entity EJB containers do not have access to the underlying data store, the EJB cannot take advantage of optimized database techniques for deleting a massive amount of data. This can have a huge performance and portability impact.

  • BMP containers cannot do automatic primary key and table generation: One of the features in WebLogic Server's container implementation is the ability to create tables, set up relationships, and generate database-generated primary keys automatically. By having the container automatically create the appropriate tables and relationships when they don't exist, development time is shortened since a time-consuming mapping of the EJB to the database doesn't have to occur. Additionally, most databases offer the ability to automatically generate a universally unique primary key value. Entity EJBs can leverage the database-generated primary key values if the container can query the database and pull that information into the server.

    It's impossible for a BMP container to create database tables or set up relationships in any way. Additionally, primary key generation techniques are proprietary based on the database being used, and cannot be done portably using a BMP entity EJB.

Conclusion
CMP entity EJBs are not used enough in production systems and BMP implementations are used too frequently for the wrong reasons. When you implement your next project, consider the strengths in performance and reduction in development that can be added by leveraging a high-quality CMP container as opposed to developing data access logic using a BMP architecture. I guarantee you'll be happy with the results.

About the Author


Tyler Jewell is BEA's director of technology evangelism and the coauthor of Mastering Enterprise JavaBeans 2.0 and Professional Java Server Programming (J2EE 1.3). He writes widely on the Web on the subject of both J2EE and Web services.

Copyright © 2002 SYS-CON Media, Inc.