企業應用常涉及複雜業務關係。EJB 1.x 時代,開發者需在 ejbCreate()、ejbActivate()、ejbPassivate() 手寫持久化邏輯,或改用 BMP。EJB 2.0 引入 Container-Managed Relationships (CMR),由容器自動管理實體 Bean 間的持久化、載入與關聯完整性,極大簡化開發。
java.util.Collection 或 Set。<relationships> 標籤中,容器據此管理關聯。<ejb-relation>
<ejb-relation-name>User-Demographics</ejb-relation-name>
<ejb-relationship-role> ... <multiplicity>One</multiplicity> ... <cmr-field><cmr-field-name>demographics</cmr-field-name></cmr-field> </ejb-relationship-role>
<ejb-relationship-role> ... <multiplicity>One</multiplicity> ... <cascade-delete/> ... </ejb-relationship-role>
</ejb-relation>
關鍵標籤:multiplicity(One/Many)、cmr-field(關聯欄位名)、cascade-delete(級聯刪除,標記於子 Bean 端)。
| 類型 | 說明 | 經典範例 |
|---|---|---|
| 一對一單向 | 父參考單一子實體 | 客戶-地址 |
| 一對一雙向 | 雙向參考 | 客戶-信用卡 |
| 一對多單向 | 父參考多子,子無需回參父 | 客戶-電話號碼 |
| 一對多雙向 | 雙向參考,父擁有多子 | 客戶-訂單 |
| 多對一單向 | 多父參考單一子 | 機票訂位-航班 |
| 多對多單向 | 多父參考多子,無需反查 | 訂位-多航段 |
| 多對多雙向 | 雙向多對多 | 活動-地點 |
註:多對一雙向實質等同一對多雙向。
CMR 強制使用 Local Interface,限制關係必須在同一 JVM 內,無法跨分散式實體 Bean。但呼叫無遠端開銷,效能極高,如同本地 Java 方法呼叫。
// CustomerBean
public abstract class CustomerBean implements EntityBean {
public abstract String getCustomerName(); // PK
public abstract AddressLocal getAddress(); // CMR 欄位
public abstract void setAddress(AddressLocal addr);
}
// AddressBean(無 CMR 欄位)
public abstract class AddressBean implements EntityBean {
public abstract String getAddress(); // PK
}
部署描述檔設定 multiplicity 均為 One,Customer 端含 cmr-field,Address 端含 cascade-delete。
// AddressBean 新增
public abstract CustomerLocal getCustomer();
public abstract void setCustomer(CustomerLocal customer);
部署描述檔 Address 端加入 cmr-field customer,即可雙向導航。
// CustomerBean
public abstract Collection getPhones();
public abstract void setPhones(Collection phones);
部署描述檔 Customer 端 multiplicity = One,Phone 端 = Many,含 cascade-delete。雙向需 Phone 端加 getCustomer()/setCustomer() 與對應 cmr-field。
// CustomerBean
public abstract Collection getWebPages();
public abstract void setWebPages(Collection pages);
// WebpageBean
public abstract Collection getCustomers();
public abstract void setCustomers(Collection customers);
部署描述檔雙端 multiplicity = Many,**不加 cascade-delete**(否則刪一客戶會刪所有網頁)。