在域模型(實體域)中,關聯關系是類與類之間最普遍的關系。根據UML語言,關系是有方向的。下面以客戶(Customer)和訂單(Order)的關系為例,闡述一下ORM的中的一對多映射:
我們知道,在關系數據庫中,只存在外鍵參照關系,而且總是由“many”方參照“one“方。
1.建立多對一單向關聯——Order(many)--->Customer(one):
-------------------------------Order.java--------------------------------











多對一單向關聯(many方)





not-null屬性會影響Hiberntae的運行時行為,Hibernate在保存Order對象時,會先檢查它的customer屬性是否為null:
若為null:在執行session.save(Order)時會拋出PropertyValueException異常;
原因很簡單:既然Customer為null,那么對應的外鍵Customer_Id也為null,試問外鍵都沒有,Order表的數據能插得進去嗎
若將not-null 屬性設為false:表示外鍵引用可以為null,試想一下,數據庫數據可以插進去嗎?
我們來看:在執行session.save(Order)時,發出了sql語句:insert into......
但是當Hibernate自動清理(flush)緩存時,拋出新的異常:TransientObjectException
所謂清理是提交事務或手動Flush,將session與數據庫保持同步,很顯然不可能同步嘛,Order對象雖然持久化,但Customer沒有.
注:是否應該把<many-to-one>的not-null屬性設為true,這根據實際業務而定。通常,訂單總是由客戶自己發出,因此建議設為true.
b. 級聯保存與更新
默認情況下,Hibernate持久化一個對象,不會自動持久化所關聯的其它臨時對象,因此會有TransientObjectException,
想它關聯也可以,<many-to-one>中加個屬性cascade="save-update"即可.
2.建立一對多關聯——Customer(one)--->Order(many):
-----------------------------Customer.java-------------------------------
















在映射一對多的雙向關聯時,應該在“one”方把inverse屬性設為true,這樣可提高應用性能。
inverse:控制反轉,為true表示反轉,由它方負責;反之,不反轉,自己負責;
如果不設,one和many兩方都要負責控制,因此,會引發重復的sql語句以及重復添加數據,
在建立兩個象的雙向關系時,應該同時修改關聯兩端的對象屬性:
customer.getOrders().add(order);
order.setCustomer(customer);
這樣做可提高業務邏輯的獨立性,使業務邏輯的程序代碼不受Hibernate實現的影響。同理解除雙向關系也一樣。
b. 級聯刪除(從數據庫刪除相關表記錄)
當刪除Customer對象時,及聯刪除Order對象.只需將cascad屬性設為delete即可.
注:刪除后的對象,依然存在于內存中,只不過由持久化態變為臨時態.
c. 父子關系(邏輯刪除,只是解除了關聯關系)
自動刪除不再和Customer對象關聯的Order對象.只需將cascade屬性設為delete-orphan.
customer.getOrders().remove(order);
order.setCustomer(null);
注:當關聯雙方都存在父子關系,就可以把父方的cascade屬性設為delete-orphan,所謂父子關系,是由父方來控制子方的生命周期.