This synthesis compares how BMP (Bean-Managed Persistence) and CMP (Container-Managed Persistence) handle entity bean relationships (1:1, 1:N, M:N) and directionality.
| Aspect | BMP (Bean-Managed) | CMP (Container-Managed) |
|---|---|---|
| Persistent Fields | Concrete instance variables | Abstract getters/setters, no fields |
| 1:1 Relationship | Manual JNDI lookup + findByPrimaryKey() in ejbLoad(); getPrimaryKey() in ejbStore() | <cmr-field> in deployment descriptor; container manages |
| 1:N Relationship | Vector + JNDI lookup of other bean’s Home in ejbLoad() | Collection CMR field + <multiplicity>Many</multiplicity> |
| M:N Relationship | Two 1:N relationships via junction table; manual JDBC | Two Collection CMR fields, both with <multiplicity>Many</multiplicity> |
| Directionality | Code both get/set methods (bidirectional) or omit one side (unidirectional) | Add/remove <cmr-field> entries in deployment descriptor |
| ejbLoad/ejbStore | Contains JNDI lookups, SQL, FK↔stub conversion | Empty — container handles everything |
| Deployment Descriptor | Standard EJB declaration | Additional <relationships> section with <ejb-relation> entries |
| Code Complexity | High — lots of boilerplate | Low — just abstract methods + XML |
- BMP:
OrderBeanholdsShipmentstub. InejbLoad(): JNDI lookupShipmentHome, callfindByPrimaryKey(shipmentFK). InejbStore():shipment.getPrimaryKey()to get FK for SQL UPDATE. - CMP:
public abstract Shipment getShipment(). XML:<cmr-field><cmr-field-name>shipment</cmr-field-name></cmr-field>. Container does the rest.
- BMP: “One” side holds
Vectorof stubs.ejbLoad()does JNDI lookup of “many” side Home, callsfindByXxx(oneSidePK). - CMP: “One” side:
public abstract Collection getChildren(). XML:<multiplicity>Many</multiplicity>on “many” side.
- BMP: Both sides hold
Vectorof other’s stubs. Each does JNDI lookup of the other’s Home with finder based on own PK. Junction table managed manually. - CMP: Both sides:
public abstract Collection getOtherSide(). Both sides in XML:<multiplicity>Many</multiplicity>. Container creates and manages junction table.
| Direction | BMP | CMP |
|---|---|---|
| Bidirectional | Both beans have get/set for each other | Both beans have <cmr-field> in descriptor |
| Unidirectional | One bean lacks get/set for the other | One bean lacks <cmr-field> in descriptor |
- CMP reduces code dramatically: What takes 50+ lines of JNDI/SQL in BMP takes 2-3 lines of abstract methods + a few XML tags in CMP.
- BMP gives control: You can optimize SQL, add custom logic in relationship loading. CMP delegates everything to container.
- CMP requires deployment descriptor expertise: Relationships are defined in XML, not Java code — harder to debug.
- FK↔stub conversion is the core BMP pain: Every
ejbLoad/ejbStoremust convert between database foreign keys and EJB object stubs. - Directionality is independent of cardinality: Both 1:1, 1:N, and M:N can be bidirectional or unidirectional in either BMP or CMP.
- BMP — manual relationship implementation
- CMP — automatic relationship management via CMR
- One-to-One Relationship — 1:1 cardinality
- One-to-Many Relationship — 1:N cardinality
- Many-to-Many Relationship — M:N cardinality
- Bidirectional vs Unidirectional — directionality concept
- CMP Abstract Accessors — CMP’s method declarations
- EJB-QL — CMP uses EJB-QL for relationship queries