簡體   English   中英

休眠:session.load 與 session.get

[英]Hibernate: session.load vs session.get

我的印象是session.load()在緩存中加載代理對象,而session.get()總是命中數據庫,但在觀看 JavaBrains視頻后我感到困惑。

根據這個視頻,當我們調用下面的 get 方法時,它正在內存中加載UserDetails的代理對象。

user = (UserDetails) session.get(UserDetails.class, 1); 

UserDetails結構是

在此處輸入圖片說明

在評論區,有網友評論道:

沒有 User 類的代理,而是創建了集合的代理對象。

現在這里有兩個問題。

第一:在 session.load() 和 session.get() 的情況下與獲取策略和創建代理對象相關,我在下面回答了這個問題。

第二:在這種情況下,代理對象將為 UserDetails 或集合創建(仍有待回答)。

謝謝

1.Fetching Strategies:在 session.get 或 session.load ( https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch20. html#performance-fetching-lazy )。

2. Session.get:從不返回 proxy ,根據 hibernate 文檔:( https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html#get(java.lang.類,java.io.Serializable))

返回具有給定標識符的給定實體類的持久實例,如果沒有這樣的持久實例,則返回 null。 (如果實例已經與會話關聯,則返回該實例。此方法永遠不會返回未初始化的實例。)

意味着get方法首先檢查緩存是否存在fully initialize object ,如果是,則返回該對象,否則它會hits the database to get the object並在將其保存在緩存空間中后返回相同的內容。

3. Session.load:根據休眠文檔:

假設實例存在,返回具有給定標識符的給定實體類的持久實例。 當訪問非標識符方法時,此方法可能返回按需初始化的代理實例。

意味着load方法首先檢查緩存是否存在fully initialize object ,如果存在則返回該對象,否則返回代理(代理是委托給另一個對象的類。最初,當它未初始化時,它只包含主要鍵。當你調用一個方法時,正如 Javadoc 所說,它通過從數據庫加載實際實體,並通過“假設該實例存在”來初始化該對象的實際實體)。

注意:重要的是要注意load方法never throw an exception 。如果您嘗試從代理對象檢索任何其他屬性而不是主鍵,您將獲得ObjectNotFoundException 。因為它將命中數據庫以從那里加載對象,這不存在。

這里, UserDetails是父級, Address是子級。 Hibernate 實際上是延遲加載子Address 因此,最終在加載父元素(在本例中為UserDetails )時,不會預加載所有子元素(在本例中為Address )。

所以,當你這樣做時:

user = (UserDetails) session.get(UserDetails.class, 1); 

Hibernate 實際上並未加載所有子項( Collection<Address> )。 而是 Hibernate 僅在您顯式訪問它們時加載Address 因此,除非您確實需要它們,否則 Hibernate 不會為Address表命中 DB,這就是延遲加載的目的。

延遲加載意味着當您獲得UserDetails的代理對象時,除非您嘗試顯式訪問 Collection 元素,否則它不會真正命中Address表。 換句話說,您需要遍歷 Hibernate 的集合以獲取Address表。

您可能會陷入每次為每個孩子( Address )訪問數據庫的情況。 因此,顯式調用listOfAddresses.size()以便一次加載所有子項。

另請注意,對於一對多多對多情況,默認情況下會發生延遲加載

2 Ques Ans:您可以說,代理將是您的問題上下文的地址。 在深度或細節上,首先hibernate也將為userdetail創建代理,但是一旦查詢命中該代理就會有數據。 但是由於hibernate默認是延遲加載而Address是UserDetail中的子節點,它將僅作為代理返回,並且您將只獲得Address(主鍵值)的id值。 不要對代理感到困惑。 將為所有類(父類(UserDetail)或子類(Address))創建代理,但對於子類,它將只具有id數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM