2010年9月2日 星期四

[Hibernate]實作 POJO 注意事項

在 Hibernate 文件中有一段話
(at Hibernate Reference 3.5.1, section 4.1.3. Prefer non-final classes )



A central feature of Hibernate, proxies, depends upon the persistent class being either non-final,
or the implementation of an interface that declares all public methods.
You can persist final classes that do not implement an interface with Hibernate. You will not,
however, be able to use proxies for lazy association fetching which will ultimately limit your options
for performance tuning.
You should also avoid declaring public  final methods on  the non-final classes.  If you want
to  use  a  class with  a  public  final method,  you must  explicitly  disable  proxying  by  setting
lazy="false".

大致意思就是 POJO Class 不要宣告成 final,method 也不要宣告成 final,否則就會無法順利使用 lazy 的功能

Hibernate 的文件我還沒仔細的看過一次,所以前幾天我就遇到了這個問題,困擾了我好幾天

我自己寫了一個 base bean,這個 base bean 提供了一些共同要實作的東西,例如 id。而在這個 base bean 中我將 id 及其 getter setter 設成了 final,且在 toString 中 回傳包括 id 的字串
而我的 pojo class 都繼承了這個 base bean
假設現在有 A、B 兩個 pojo class,A 的 b 屬性關聯到 B,並且 A 有 getB() 可回傳 B

問題是這樣的
當我行 db query 出 a 後(a 是 A 的實體),再用 a.getB() 得到 b (b 是 B 的實體),此時 print b.getId() 是 null,但 print b.toString() 卻又看得到正確的 id 值,感覺就像見鬼了一樣 >"<

因有其他事要忙,也沒仔細去查,後來專心查時才發現,b.getClass().getName 得到的並不是我的 B,而是一個類似像 B_$$_javassist_9 這樣的 class,追蹤下去後才知道這是為了 lazy 的效果,所有 hibernate 會用 javassist 來繼承我們的 pojo,並 override 各 method ,產生另一個 class,所以當我在 base bean 將 method 設成 final 後,它就無法正常的去 override,導致無法得到預期的結果

後來想說既然有這樣的問題,那麼 hibernate 的文件應該會有提到,於是再回頭查文件,果然就看到了這一段

沒有留言:

張貼留言

廣告訊息會被我刪除

Related Posts with Thumbnails