Hazırda Bekletme'de bire bir, çoktan bire ve bire çok için varsayılan getirme türü


104

Hazırda bekletme eşlemelerinde varsayılan getirme türü nedir?

Keşfettikten sonra bilmem gereken şey:

  • bire bir heveslidir .
  • bire çok için tembeldir .

Ancak Eclipse'de test ettikten sonra herkes için hevesliydi.

JPA veya Hazırda Bekletme kullanıp kullanmama bağlı mı?


1
Hala JPA konularıyla ilgileniyorsanız - Sorunuzu yeni bir yanıtla güncelledim, çünkü eski yanıtlar mevcut Hazırda Bekletme sürümü için geçerliliğini yitirdi.
Alexander Rühl

Yanıtlar:


194

JPA veya Hazırda Bekletme kullanıp kullanmadığınıza bağlıdır.

Gönderen JPA 2.0 spec , varsayılan değerler:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

Ve kış uykusunda, her şey Tembel

GÜNCELLEME:

Hibernate'in en son sürümü, yukarıdaki JPA varsayılanlarıyla uyumludur.


11
"Ve hazırda bekletme modunda, her şey Tembeldir" görünüşe göre son sürümlerde değişti. Lütfen aşağıdaki Alexander Rühl'ün cevabına bakın .
Dinei

1
Hazırda bekletme, JPA uygulamalarından biridir, bu nedenle Hazırda Bekletme'yi kullandığınızda, JPA kullanıyorsunuz :)
xenteros

Bu popüler bir sorgu. @Ashish Agarwal Lütfen cevabınızın son satırını günceller misiniz? Hazırda Bekletme'de artık Tembel değil.
Saurabh Tiwari

Gönderi, en son Hazırda Bekletme davranışına göre güncellendi.
M Anouti

Her eşleme için istekli olan varsayılan getirme türü olduğunu iddia eden bir güncelleme yapıldı, bu hem mevcut 5.x hem de yeni 6.x Hazırda Beklet belgelerinde bölüm 11.3 tarafından reddedildi, bu yüzden düzenlemeyi geri aldım. Ayrıca, otomatik istekliliğin olmaması tavsiyeye aykırıdır, çünkü bu, tek bir nesneyi getirirken muhtemelen tüm veritabanını seçmek anlamına gelir.
Alexander Rühl

52

Soruyu sorarken yanıtların doğru olduğunu biliyorum - ancak insanlar (bu dakika benim gibi) hala WildFly 10'larının neden farklı davrandığını merak ettiklerinden, mevcut Hibernate 5 için bir güncelleme yapmak istiyorum .x sürümü:

In hazırda 5.2 Kullanım Kılavuzu o bölümde belirtilmiştir 11.2. Getirme stratejileri uygulama :

Hazırda Bekletme önerisi, tüm ilişkileri durağan olarak işaretlemek ve istek için dinamik getirme stratejileri kullanmaktır. Bu ne yazık ki, tüm bire bir ve çoktan bire ilişkilerin varsayılan olarak hevesle getirilmesi gerektiğini tanımlayan JPA spesifikasyonuyla çelişmektedir . Bir JPA sağlayıcısı olarak Hibernate, bu varsayılanı kabul eder.

Bu nedenle Hibernate, yukarıda JPA için Ashish Agarwal gibi davranır:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(bkz JPA 2.1 Spesifikasyonu )


Ya JPA impl yerine yerel hazırda bekletme modunu kullanırsak, aynı şekilde davranır mı?
jMounir

@jMounir: Bunu denemedim ama Hibernate, JPA'da tanımlandığı gibi davrandığını belirttiğinden, Hibernate'i kendisi için kullanırken bunun neden farklı olacağını anlamıyorum. Her iki durumda da biri varsayılan stratejiyi geçersiz kılabilir.
Alexander Rühl

15

Sorunuzu yanıtlamak için Hibernate, JPA standardının bir uygulamasıdır. Hazırda bekletme işleminin kendine özgü tuhaflıkları vardır, ancak Hazırda Bekletme belgelerine göre

Varsayılan olarak, Hibernate, koleksiyonlar için geç seçme getirme ve tek değerli ilişkilendirmeler için geç proxy getirme kullanır. Bu varsayılanlar, uygulamaların çoğunda çoğu ilişkilendirme için anlamlıdır.

Bu nedenle, Hazırda Bekletme, beyan ettiğiniz ilişki türü ne olursa olsun, her zaman tembel bir getirme stratejisi kullanarak herhangi bir nesneyi yükleyecektir. Bire bir veya çoktan bire ilişkide tek bir nesne için tembel bir proxy (başlatılmamış olmalı, ancak boş olmamalıdır) ve erişmeye çalıştığınızda değerlerle hidratlayacağı boş bir koleksiyon kullanacaktır. .

Hibernate'in, siz belirtmediğiniz sürece, nesneye erişmeye çalıştığınızda bu nesneleri yalnızca değerlerle doldurmaya çalışacağı anlaşılmalıdır fetchType.EAGER.


0

Tek değerli ilişkilendirmeler için, yani Bire Bir ve Çoktan Bire: -
Varsayılan Lazy = proxy
Proxy lazy loading : - Bu, ilişkili varlığınızın bir proxy nesnesinin yüklendiğini gösterir. Bu, ilişkili varlığın proxy nesnesi için yalnızca iki varlığı birbirine bağlayan kimliğin yüklendiği anlamına gelir.
Örneğin: A ve B, Çoktan bire ilişkilendirmeye sahip iki varlıktır. Yani: Her B için birden fazla A olabilir. A'nın her nesnesi bir B referansı içerecektir.
''

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
A ilişkisi sütunları (yardım, teklif, ... A varlığının diğer sütunları) içerecektir.
B ilişkisi sütunları (bid, ... B varlığının diğer sütunları) içerecektir.

Proxy, A getirildiğinde, B için sadece id'nin getirildiğini ve B'nin sadece id içeren bir proxy nesnesinde saklandığını ima eder. B'nin vekil nesnesi, yalnızca asgari alanlarla B'nin bir alt sınıfı olan vekil sınıfının bir nesnesidir. Teklif halihazırda A ilişkisinin bir parçası olduğundan, B ilişkisinden teklif almak için bir sorgu başlatmak gerekli değildir. B varlığının diğer özellikleri, yalnızca teklif dışında bir alana erişildiğinde tembel olarak yüklenir.

Koleksiyonlar için, yani -Çoktan-Çoğa ve Bire-Çoğa: -
Varsayılan Lazy = true


Ayrıca getirme stratejisinin (seçme, birleştirme vb.) Tembelliği geçersiz kılabileceğini de unutmayın. yani: tembel = 'doğru' ve getir = 'birleştirme' ise, A'nın getirilmesi B veya B'leri de getirecektir (Koleksiyon olması durumunda). Bir düşünürsen sebebini anlayabilirsin.
Tek değerli ilişkilendirme için varsayılan getirme "birleştirme" dir.
Koleksiyonlar için varsayılan getirme "seç" tir. Lütfen son iki satırı doğrulayın. Bunu mantıklı bir şekilde çıkardım.

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.