Company與Employee類之間為一對多多態關聯關系
如果繼承關系樹的根類對應一個表
或者每個類對應一個表
那麼就能映射Company類的employees集合
本節介紹如何映射多對一多態關聯
如圖
所示
ClassD與ClassA為多對一多態關聯關系
圖 ClassD與ClassA為多對一多態關聯關系 ClassA
ClassB和ClassC構成了一棵繼承關系樹
如果繼承關系樹的根類對應一個表
或者每個類對應一個表
那麼可以按以下方式映射ClassD的a屬性
<many
to
one name=
a
class=
ClassA
column=
A_ID
cascade=
save
update
/>
假定與ClassD對應的表為TABLE_D
與ClassA對應的表為TABLE_A
在TABLE_D中定義了外鍵A_ID
它參照TABLE_A表的主鍵
ClassD對象的a屬性既可以引用ClassB對象
也可以引用ClassC對象
例如
tx = session
beginTransaction();
ClassD d=(ClassD)session
get(
ClassD
id);
ClassA a=d
getA();
if(a instanceof ClassB)
System
out
println(((ClassB)a)
getB
());
if(a instanceof ClassC)
System
out
println(((ClassC)a)
getC
());
mit();
以下代碼在映射ClassD類的a屬性時使用了延遲檢索策略
<many
to
one name=
a
class=
ClassA
column=
A_ID
lazy=
true
cascade=
save
update
/>
當Hibernate加載ClassD對象時
它的屬性a引用ClassA的代理類實例
在這種情況下
如果對ClassA的代理類實例進行類型轉換
會拋出ClassCastException
ClassA a=d
getA();
ClassB b=(ClassB)a; //拋出ClassCastException
解決以上問題的一種辦法是使用Session
load()方法
ClassA a=d
getA();
ClassB b=(ClassB)session
load(ClassB
class
a
getId());
System
out
println(b
getB
());
當執行Session的load()方法時
Hibernate並不會訪問數據庫
而是僅僅返回ClassB的代理類實例
這種解決辦法的前提條件是必須事先知道ClassD對象實際上和ClassA的哪個子類的對象關聯
解決以上問題的另一種辦法是顯式使用迫切左外連接檢索策略
避免Hibernate創建ClassA的代理類實例
而是直接創建ClassA的子類的實例
tx = session
beginTransaction();
ClassD d=(ClassD)session
createCriteria(ClassD
class)
add(Expression
eq(
id
id))
setFetchMode(
a
FetchMode
EAGER)
uniqueResult();
ClassA a=d
getA();
if(a instanceof ClassB)
System
out
println(((ClassB)a)
getB
());
if(a instanceof ClassC)
System
out
println(((ClassC)a)
getC
());
mit();
如果繼承關系樹的具體類對應一個表
為了表達ClassD與ClassA的多態關聯
需要在TABLE_D中定義兩個字段
A_ID和A_TYPE
A_TYPE字段表示子類的類型
A_ID參照在子類對應的表中的主鍵
圖
顯示了表TABLE_D
TABLE_B和TABLE_C的結構
educitycn/img_///jpg> 圖 表TABLE_DTABLE_B和TABLE_C的結構
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28679.html