Hazırda Bekletme: session.get ve session.load arasındaki fark


88

API'den proxy ile bir ilgisi olduğunu görebiliyordum. Ancak proxy hakkında çok fazla bilgi bulamadım ve arama session.getile session.load. Arasındaki farkı anlamadım . Birisi beni bir referans sayfasına açıklayabilir veya yönlendirebilir mi?

Teşekkür ederim!!

Yanıtlar:


117

Gönderen hazırda forumu :

Bu, Hazırda Bekleme kitabından. İyi biri bunu okudu ..


Tanımlayıcıya göre nesneleri alma Aşağıdaki Hazırda Bekletme kod parçacığı, veritabanından bir Kullanıcı nesnesi alır:

User user = (User) session.get(User.class, userID);

Get () yöntemi özeldir çünkü tanımlayıcı, bir sınıfın tek bir örneğini benzersiz şekilde tanımlar. Bu nedenle, uygulamaların tanımlayıcıyı kalıcı bir nesne için uygun bir tutamaç olarak kullanması yaygındır. Tanımlayıcıya göre geri alma, bir nesneyi alırken önbelleği kullanabilir ve nesne zaten önbelleğe alınmışsa veritabanı isabetini önler. Hazırda bekletme ayrıca bir load () yöntemi sağlar:

User user = (User) session.load(User.class, userID);

Load () yöntemi daha eskidir; get (), kullanıcı isteği nedeniyle Hazırda Bekletme API'sına eklendi. Fark önemsiz:

Load () nesneyi önbellekte veya veritabanında bulamazsa, bir istisna atılır. Load () yöntemi hiçbir zaman null döndürmez. Get () yöntemi, nesne bulunamazsa null döndürür.

Load () yöntemi, gerçek bir kalıcı örnek yerine bir proxy döndürebilir. Proxy, ilk kez erişildiğinde gerçek nesnenin yüklenmesini tetikleyen bir yer tutucudur; Öte yandan, get () hiçbir zaman bir proxy döndürmez. Get () ve load () arasında seçim yapmak kolaydır: Kalıcı nesnenin var olduğundan eminseniz ve yokluğun istisnai olduğu düşünülürse, load () iyi bir seçenektir. Verilen tanımlayıcıya sahip kalıcı bir örnek olup olmadığından emin değilseniz get () kullanın ve boş olup olmadığını görmek için geri dönüş değerini test edin. Load () kullanımının başka bir anlamı vardır: Uygulama, kalıcı durumunu almak için veritabanına vurmadan kalıcı bir örneğe geçerli bir referans (bir proxy) alabilir. Bu nedenle load (), kalıcı nesneyi önbellekte veya veritabanında bulamadığında bir istisna atmayabilir; istisna, daha sonra proxy'ye erişildiğinde atılır. Elbette, bir nesneyi tanımlayıcıya göre almak, rastgele sorgular kullanmak kadar esnek değildir.


1
Şu anda session.Get <T> () 'nin bir proxy döndürdüğü yerde hata ayıklama yapıyorum!
Kent Boogaart

7
Çok teşekkürler! Benim için para kısmı şuydu: "Load () nesneyi önbellekte veya veritabanında bulamazsa, bir istisna atılır. Nesne bulunamazsa get () yöntemi boş döndürür."
Chris

15
Session.get için JavaDoc diyor ki: Verilen tanımlayıcıyla verilen varlık sınıfının kalıcı örneğini döndür veya böyle kalıcı bir örnek yoksa null. (Örnek veya örnek için bir proxy zaten oturumla ilişkiliyse, o örneği veya proxy'yi döndürün.) Yani kitaptan "Diğer yandan, get () hiçbir zaman bir proxy döndürmez" yazan bölüm. Doğru değil.
Vicky

dao'larınızla bir işlem yönetimi stratejisi kullanıyorsanız get () 'yi tercih edebilirsiniz. aksi takdirde, load () bir proxy döndürürse, arayanın açık bir hazırda bekletme oturumu bağlamında da yürütülmesi gerekecektir. örneğin, MVC yapıyorsanız, denetleyiciniz dao.load () çalıştırabilir ve daha sonra geçerli bir oturum yoksa proxy nesnesine erişmeye çalışırken bir istisna atabilir. dao.get () yapmak, oturumdan bağımsız olarak gerçek nesneyi denetleyiciye geri döndürecektir (var olduğunu varsayarak)
dev

@Vicky'nin tanımladığı sorun baş ağrısına neden olabilir ve bunun herhangi bir avantajını görmüyorum. Bazı durumlarda, daha fazla parametrik sorgular için ek olarak tanımlayıcıya ihtiyacım var. Ancak nesnenin bir vekili zaten oturumda olduğundan, tanımlayıcının alıcısı boş döndürür. Eğer bu proxy oturumdaysa neden gerçek örnek yerine proxy'yi alıyorlar?
djmj

15

En azından nhibernate olarak, session.Get (id) nesneyi veritabanından yüklerken, session.Load (id) sunucunuzdan ayrılmadan ona sadece bir proxy nesnesi oluşturur. POCO'larınızdaki (veya POJO'larınızdaki :) diğer tembel yüklü mülkler gibi çalışır. Daha sonra bu proxy'yi ilişkiler vb. Oluşturmak için nesnenin kendisine bir referans olarak kullanabilirsiniz.

Bunu, sadece kimliği tutan ve ihtiyacınız olduğunda geri kalanını yükleyecek bir nesneye sahip olmak gibi düşünün. İlişki oluşturmak için (FK'ler gibi) etrafta dolaşıyorsanız, ihtiyacınız olan tek şey kimliktir.


Yani, load (id) 'nin önce geçerli bir id olup olmadığını kontrol etmek için veritabanına vuracağını ve daha sonra proxy nesnesini döndüreceğini ve bu nesnenin özelliklerine erişildiğinde veritabanına tekrar çarptığını mı söylemek istiyorsunuz? bu beklenmedik bir senaryo değil mi? tek nesneyi yüklemek için iki sorgu?
faisalbhagat

Hayır, load (id), kimliği hiçbir şekilde doğrulamayacağından, DB'ye gidiş dönüş olmayacaktır. Yalnızca geçerli olduğundan emin olduğunuzda kullanın.
Jorge Alves

9

session.load (), veritabanına basmadan her zaman bir "proxy" (Hazırda bekletme terimi) döndürür. Hazırda bekletme modunda proxy, verilen tanımlayıcı değerine sahip bir nesnedir, özellikleri henüz başlatılmamıştır, sadece geçici bir sahte nesne gibi görünür. Satır bulunmazsa, bir ObjectNotFoundException oluşturur.

session.get () her zaman veritabanını vurur ve proxy'yi değil veritabanı satırını temsil eden bir nesne olan gerçek nesneyi döndürür. Satır bulunmazsa, boş döndürür.

Bu yöntemlerle performans da farklılık yaratır. ikisi arasında...


Üzerinde aynı ifadeler mkyong.com/hibernate/... (Ama önce kim bilmiyorum)
bish

3

Bir Ekstra puan daha:

Hibernate Session sınıfının get yöntemi, nesne önbellekte ve veritabanında bulunmazsa null döndürür. load () yöntemi, nesne önbellekte olduğu gibi veritabanında da bulunmazsa ancak hiçbir zaman null döndürmezse ObjectNotFoundException oluşturur.


2

"Al" yerine "yükle" kullanmanın dolaylı bir sonucu, bir sürüm özniteliği kullanan iyimser kilitlemenin beklediğiniz gibi çalışmayabilmesidir. Bir yük yalnızca bir proxy oluşturur ve veritabanından okumazsa, version özelliği yüklenmez. Sürüm yalnızca / daha sonra nesne üzerindeki bir özelliğe başvurursanız, bir seçimi tetiklerseniz yüklenir. Bu arada, başka bir oturum nesneyi güncelleyebilir ve oturumunuz iyimser kilit kontrolünü yapması gereken orijinal sürüme sahip olmayacaktır - bu nedenle oturumunuzun güncellemesi diğer oturumun güncellemesinin üzerine herhangi bir uyarı olmadan yazacaktır.

İşte aynı tanımlayıcıya sahip bir nesneyle çalışan iki oturumla bu senaryoyu taslak haline getirme girişimi. DB'deki nesne için ilk sürüm 10'dur.

Session 1                  Session 2
---------                  ---------
Load object
Wait a while..   
                           Load object
                           Modify object property
                           [triggers db 'select' -
                            version read as 10]
                           Commit
                           [triggers db update,
                            version modified to 11]
Modify object property
  [triggers db 'select' -
  version read as 11]
Commit
  [triggers db update,
  version modified to 12]

Aslında 1. oturumun kararlılığının iyimser bir kilit istisnasıyla başarısız olmasını istiyoruz, ancak burada başarılı olacak.

"Load" yerine "get" kullanmak sorunu çözer, çünkü get hemen bir seçim yapar ve iyimser kilit kontrolü için sürüm numaraları doğru zamanlarda yüklenecektir.


0

Ayrıca, nesne mevcut değilse bir istisna atacağından, yükü kullanırken dikkatli olmalıyız. Onu yalnızca nesnenin var olduğundan emin olduğumuzda kullanmalıyız.


0

Http://www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load () adresinde mükemmel bir açıklama bulunur :
Her zaman bir "proxy" (Hazırda bekletme süresi) döndürmez. veritabanına isabet.
Hazırda bekletme modunda proxy, verilen tanımlayıcı değerine sahip bir nesnedir, özellikleri henüz başlatılmamıştır, sadece geçici bir sahte nesne gibi görünür.
Veritabanında kimlik değeri olmasa bile, her zaman verilen kimlik değerine sahip bir proxy nesnesi döndürür. Ancak, özelliklerini veritabanından alarak bir proxy'yi başlatmaya çalıştığınızda, veritabanına select deyimi ile vurur. Satır bulunmazsa, bir ObjectNotFoundException atılır.
session.get ():
Her zaman veritabanını vurur (önbellekte bulunmazsa) ve proxy'yi değil veritabanı satırını temsil eden bir nesne olan gerçek nesneyi döndürür.
Satır bulunmazsa, boş döndürür.


0

load () nesneyi önbellekten veya veritabanından bulamazsa, bir istisna atılır ve load () yöntemi hiçbir zaman null döndürmez.

get () yöntemi, nesne bulunamazsa null döndürür. Load () yöntemi, gerçek bir kalıcı örnek yerine bir proxy döndürebilir get () hiçbir zaman bir proxy döndürmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.