您好,登錄后才能下訂單哦!
小編給大家分享一下Hinerbate單端關聯(lián)代理的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在Hinerbate中,對集合的延遲抓取的采用了自己的實現(xiàn)方法。但是,對于Hinerbate單端關聯(lián)的延遲抓取,則需要采用 其他不同的機制。Hinerbate單端關聯(lián)的目標實體必須使用代理,Hihernate在運行期二進制級(通過優(yōu)異的CGLIB庫), 為持久對象實現(xiàn)了延遲載入代理。
默認的,Hibernate3將會為所有的持久對象產生代理(在啟動階段),然后使用他們實現(xiàn)多對一(many-to-one)關聯(lián)和一對一(one-to-one) 關聯(lián)的延遲抓取。
在映射文件中,可以通過設置proxy屬性為目標class聲明一個接口供代理接口使用。
默認的,Hibernate將會使用該類的一個子類。 注意:被代理的類必須實現(xiàn)一個至少包可見的默認構造函數(shù),我們建議所有的持久類都應擁有這樣的構造函數(shù)
在如此方式定義一個多態(tài)類的時候,有許多值得注意的常見性的問題,
例如:
<class name="Cat" proxy="Cat"> ...... <subclass name="DomesticCat"> ..... </subclass> </class>
首先,Cat實例永遠不可以被強制轉換為DomesticCat, 即使它本身就是DomesticCat實例。
Cat cat = (Cat) session.load(Cat.class, id); // instantiate a proxy (does not hit the db) if ( cat.isDomesticCat() ) { // hit the db to initialize the proxy DomesticCat dc = (DomesticCat) cat; // Error! .... }
其次,代理的“==”可能不再成立。
Cat cat = (Cat) session.load(Cat.class, id); // instantiate a Cat proxy DomesticCat dc = (DomesticCat) session.load(DomesticCat.class, id); // acquire new DomesticCat proxy! System.out.println(cat==dc); // false
雖然如此,但實際情況并沒有看上去那么糟糕。雖然我們現(xiàn)在有兩個不同的引用,分別指向這兩個不同的代理對象, 但實際上,其底層應該是同一個實例對象:
cat.setWeight(11.0); // hit the db to initialize the proxy System.out.println( dc.getWeight() ); // 11.0
第三,你不能對“final類”或“具有final方法的類”使用CGLIB代理。
***,如果你的持久化對象在實例化時需要某些資源(例如,在實例化方法、默認構造方法中), 那么代理對象也同樣需要使用這些資源。實際上,代理類是持久化類的子類。
這些問題都源于Java的單根繼承模型的天生限制。如果你希望避免這些問題,那么你的每個持久化類必須實現(xiàn)一個接口, 在此接口中已經聲明了其業(yè)務方法。然后,你需要在映射文檔中再指定這些接口。例如:
<class name="CatImpl" proxy="Cat"> ...... <subclass name="DomesticCatImpl" proxy="DomesticCat"> ..... </subclass> </class>
這里CatImpl實現(xiàn)了Cat接口, DomesticCatImpl實現(xiàn)DomesticCat接口。 在load()、iterate()方法中就會返回 Cat和DomesticCat的代理對象。 (注意list()并不會返回代理對象。)
Cat cat = (Cat) session.load(CatImpl.class, catid); Iterator iter = session.iterate("from CatImpl as cat where cat.name='fritz'"); Cat fritz = (Cat) iter.next();
這里,對象之間的關系也將被延遲載入。這就意味著,你應該將屬性聲明為Cat,而不是CatImpl。
但是,在有些方法中是不需要使用代理的。
例如:
◆equals()方法,如果持久類沒有重載equals()方法。
◆hashCode()方法,如果持久類沒有重載hashCode()方法。
◆標志符的getter方法。
Hibernate將會識別出那些重載了equals()、或hashCode()方法的持久化類。
若選擇lazy="no-proxy"而非默認的lazy="proxy",我們可以避免類型轉換帶來的問題。然而,這樣我們就需要編譯期字節(jié)碼增強,并且所有的操作都會導致立刻進行代理初始化。
以上是“Hinerbate單端關聯(lián)代理的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。