原文引自:http://forum.javaeye.com/viewtopic.php?t=18128
眾所周知,到了Hibernate3.0以后,關(guān)聯(lián)關(guān)系的對象默認(rèn)都是使用延遲加載,例如<one-to-many>時.但我在映射<one-to-one>,<many-to-one>關(guān)系時指定了lazy="true",但是在查詢對象時,我只想查詢一個對象,仍然會把這個對象所關(guān)聯(lián)的<one-to-one>,<many-to-one>對象一起查詢出來,這樣造成了極大的性能浪費.在不指定lazy屬性時,<many-to-one>所關(guān)聯(lián)的對象反而會延遲加載,這讓我大為困惑,還以為是Hibernate的bug.
在網(wǎng)上查找資料,說在為了延遲加載<one-to-one>,<many-to-one>所關(guān)聯(lián)的對象,需要設(shè)置被關(guān)聯(lián)的對象<class name="" lazy="true">,我也這樣做了,但是仍然沒有效果.
仔細(xì)閱讀了Hibernate的手冊,才發(fā)現(xiàn)原來要延遲加載<one-to-one>,<many-to-one>所關(guān)聯(lián)的對象時,除了要指定lazy="true"外,還需要運行期字節(jié)碼增強,而我省去了這一步,所以延遲加載沒有效果.同時還發(fā)現(xiàn)在默認(rèn)情況下,<one-to-one>,<many-to-one>的lazy屬性是"proxy"而不是"true"!因此如果直接采用lazy的默認(rèn)值,是可以延遲加載的.
總結(jié)一下:
<many-to-one>默認(rèn)的屬性是lazy="proxy",此時默認(rèn)是會延遲加載的.在指定了lazy="true"之后,必須要經(jīng)過運行期字節(jié)碼增加,延遲加載才有效果.
而<one-to-one>相對要復(fù)雜一點,延遲加載還要受到constrained屬性的限制.constrained="false"時表明實體和被關(guān)聯(lián)到的實體的約束不是強制的,即存在一個實體時,它通過<one-to-one>關(guān)聯(lián)的實體可能存在,也可能不存在,這時在查詢實體時,Hibernate總會發(fā)起一次查詢檢查<one-to-one>所關(guān)聯(lián)的實體是否存在,而這時已經(jīng)可以把one-to-one關(guān)聯(lián)的實體查詢出來了,因此在<one-to-one>關(guān)系中,如果constrained="false",總是會立即加載關(guān)聯(lián)到的實體.
如果當(dāng)constrained="true",且lazy="proxy"(默認(rèn)),是可以延遲加載的.
如果當(dāng)constrained="true",且lazy="true"時,需要經(jīng)過運行期字節(jié)碼增加,延遲加載才會奏效.
但是這里我還是有個疑問,既然在lazy="proxy"時,已經(jīng)實現(xiàn)了延遲加載的效果,為什么在lazy="true"時,還需要動態(tài)字節(jié)碼增強才能實現(xiàn)延遲加載呢?
Re: Hibernate中的延遲加載
以后在one-to-one或many-to-one中不會再有l(wèi)azy="true"了,你可以理解成no-proxy.
[1]起碼還是好的方向: 默認(rèn)就可以lazy了. 而且來了extra :)
[2]寫Hibernate的哥們也是要活命的嘛, 不改變怎么來的咨詢費, 不過Hibernate的migration寫的也還不錯.
[3]constrained如你所說, 而且我估計這個屬性以后不會有太大變更.
hope that helps :)
regards
眾所周知,到了Hibernate3.0以后,關(guān)聯(lián)關(guān)系的對象默認(rèn)都是使用延遲加載,例如<one-to-many>時.但我在映射<one-to-one>,<many-to-one>關(guān)系時指定了lazy="true",但是在查詢對象時,我只想查詢一個對象,仍然會把這個對象所關(guān)聯(lián)的<one-to-one>,<many-to-one>對象一起查詢出來,這樣造成了極大的性能浪費.在不指定lazy屬性時,<many-to-one>所關(guān)聯(lián)的對象反而會延遲加載,這讓我大為困惑,還以為是Hibernate的bug.
在網(wǎng)上查找資料,說在為了延遲加載<one-to-one>,<many-to-one>所關(guān)聯(lián)的對象,需要設(shè)置被關(guān)聯(lián)的對象<class name="" lazy="true">,我也這樣做了,但是仍然沒有效果.
仔細(xì)閱讀了Hibernate的手冊,才發(fā)現(xiàn)原來要延遲加載<one-to-one>,<many-to-one>所關(guān)聯(lián)的對象時,除了要指定lazy="true"外,還需要運行期字節(jié)碼增強,而我省去了這一步,所以延遲加載沒有效果.同時還發(fā)現(xiàn)在默認(rèn)情況下,<one-to-one>,<many-to-one>的lazy屬性是"proxy"而不是"true"!因此如果直接采用lazy的默認(rèn)值,是可以延遲加載的.
總結(jié)一下:
<many-to-one>默認(rèn)的屬性是lazy="proxy",此時默認(rèn)是會延遲加載的.在指定了lazy="true"之后,必須要經(jīng)過運行期字節(jié)碼增加,延遲加載才有效果.
而<one-to-one>相對要復(fù)雜一點,延遲加載還要受到constrained屬性的限制.constrained="false"時表明實體和被關(guān)聯(lián)到的實體的約束不是強制的,即存在一個實體時,它通過<one-to-one>關(guān)聯(lián)的實體可能存在,也可能不存在,這時在查詢實體時,Hibernate總會發(fā)起一次查詢檢查<one-to-one>所關(guān)聯(lián)的實體是否存在,而這時已經(jīng)可以把one-to-one關(guān)聯(lián)的實體查詢出來了,因此在<one-to-one>關(guān)系中,如果constrained="false",總是會立即加載關(guān)聯(lián)到的實體.
如果當(dāng)constrained="true",且lazy="proxy"(默認(rèn)),是可以延遲加載的.
如果當(dāng)constrained="true",且lazy="true"時,需要經(jīng)過運行期字節(jié)碼增加,延遲加載才會奏效.
但是這里我還是有個疑問,既然在lazy="proxy"時,已經(jīng)實現(xiàn)了延遲加載的效果,為什么在lazy="true"時,還需要動態(tài)字節(jié)碼增強才能實現(xiàn)延遲加載呢?
Re: Hibernate中的延遲加載
以后在one-to-one或many-to-one中不會再有l(wèi)azy="true"了,你可以理解成no-proxy.
[1]起碼還是好的方向: 默認(rèn)就可以lazy了. 而且來了extra :)
[2]寫Hibernate的哥們也是要活命的嘛, 不改變怎么來的咨詢費, 不過Hibernate的migration寫的也還不錯.
[3]constrained如你所說, 而且我估計這個屬性以后不會有太大變更.
hope that helps :)
regards