JPA Entity Manager kapatılmalı mı?


83

Aşağıdaki yönteme sahibim.

public Profile readUser(String email){
    EntityManager em = EMF.get().createEntityManager();
    return em.find(Profile.class, email);
}

Varlık yöneticisinin yukarıdaki kullanımı uygun mu? Ya da kapatmak gerekiyor mu? Herhangi bir öneri lütfen.



Hayır sadece hayır. Sızıntı istemiyorsanız ...

Yanıtlar:


131

Sanırım cevap şudur: duruma göre değişir .

Varlık yöneticiniz, varlıkların bulunduğu bağlama erişim sağlamanın anahtarıdır. Başvurunuz bir JSE uygulamasıysa, bağlamınızın yaşam beklentisinin ne olduğunu düşünmeniz gerekir.

Kullanıcı isteğine göre bir varlık yöneticisi oluşturacağınızı düşünelim. Böylece, belirli bir isteğe katılırken, varlık yöneticinizi açık tutarsınız ve bitirdiğinizde onu kapatırsınız.

Bir JSE uygulamasında, varlık yöneticinizi uygulamanın ömrü boyunca açık tutmak istediğinizi düşünmüş olabilirsiniz (büyük miktarda veriyle uğraşmadığınızı varsayarak), ardından uygulamanız kapandığında onu kapatırsınız.

Sonuç olarak, ne zaman açacağınız ve ne zaman kapatacağınız tamamen stratejinize ve tasarımınıza bağlıdır. Artık kendi bağlamında varlıklara ihtiyacınız kalmadığında kapatırsınız.

Örneğinizde bu açık değildir, ancak yöntemde EM'yi oluşturduğunuz için, geri dönmeden önce onu kapatmalısınız, aksi takdirde artık ona tekrar erişemezsiniz (bazı kayıt defterinde tutmadığınız sürece, kodda açık değil).

Kapatmazsanız, varlıklarınız, onları kullanmayı bitirdikten sonra bile bağlı kalacaktır. EM'nize artık erişemediğinizde bile bağlamınız canlı tutulacaktır.

JPA Şartname fazla ayrıntı içeriyor. 7.7 Uygulama tarafından yönetilen Kalıcı Bağlamlar bölümünde şöyle diyor:

Uygulama tarafından yönetilen bir varlık yöneticisi kullanıldığında, uygulama, varlık yöneticisi yaşam döngüsünü yönetmek ve kalıcılık bağlamlarını elde etmek ve yok etmek için kalıcılık sağlayıcısının varlık yöneticisi fabrikasıyla doğrudan etkileşime girer.

Tüm bu tür uygulama tarafından yönetilen kalıcılık bağlamları kapsam olarak genişletilir ve birden çok işlemi kapsayabilir.

EntityManagerFactory.createEntityManagerYöntemi ve EntityManager closeve isOpenyöntemler, bir uygulama tarafından yönetilen işletme yöneticisinin ömrünü ve ilgili kalıcılık içeriği yönetmek için kullanılır.

Genişletilmiş kalıcılık bağlamı, varlık yöneticisinin kullanılarak yaratıldığı noktadan EntityManagerFactory.createEntityManagervarlık yöneticisi ile kapatılana kadar mevcuttur EntityManager.close.

Uygulama tarafından yönetilen varlık yöneticisinden elde edilen genişletilmiş kalıcılık bağlamı, işlemle birlikte yayılmayan bağımsız bir kalıcılık bağlamıdır.

[...] EntityManager.closeYöntem, kalıcılık bağlamını ve diğer kaynakları serbest bırakmak için bir varlık yöneticisini kapatır. Yakın çağırdıktan sonra uygulama hakkında başka yöntemleri çağırmak etmemelidir EntityManagerhariç Örneğin getTransactionve isOpenya IllegalStateExceptionatılacaktır. Bir işlem etkinken kapatma yöntemi çağrılırsa, kalıcılık içeriği işlem tamamlanana kadar yönetilen olarak kalır.

EntityManager.isOpenYöntem, işletme yöneticisi açık olup olmadığını gösterir. isOpenVarlık yöneticisi kapatılana kadar yöntem true döndürür. Bunun nasıl çalıştığını gerçekten anlamak için, varlık yöneticisi ile bağlam arasındaki ilişkiyi anlamak çok önemlidir.

Gördüğünüz gibi varlık yöneticisi, varlıklarınıza eriştiğiniz genel arabirimdir, ancak varlıklarınız varlık yöneticinize eklenmiş bir bağlamda bulunur. Farklı bağlam türlerinin yaşam döngüsünü anlamak, sorunuza cevap verecektir.

Kalıcılık bağlamları farklı türlerde olabilir. Java EE uygulamalarında, işlem kapsamlı bir kalıcılık bağlamına veya genişletilmiş kalıcılık bağlamına sahip olabilirsiniz . JSE uygulamasında, bağlamın doğası geliştirici tarafından kontrol edilir .

Varlık yöneticinize bir varlık istediğinizde, varlığı ekli bağlamında arar, varlığı orada bulursa onu döndürür, aksi takdirde varlığı veritabanından alır. Bağlam içinde bu varlık için sonraki çağrılar aynı varlığı döndürür.

İşlem kapsamlı

İşlem kapsamlı kalıcılık bağlamını kullanan bir Java EE uygulamasında, varlık yöneticinize ilk kez eriştiğinizde, henüz bir bağlam yoksa, mevcut JTA işleminin bir bağlam eklenip eklenmediğini kontrol eder, yeni bir bağlam oluşturulur ve varlık yöneticisi bağlanır bu bağlamda. Daha sonra varlık veritabanından okunur (eğer varsa önbellekten) ve bağlama yerleştirilir. İşleminiz sona erdiğinde (teslim etme veya geri alma), bağlam geçersiz hale gelir ve içindeki varlıklar ayrılır. Bu, vatansız oturum fasulyeleri için klasik senaryodur.

@PersistenceContext(unitName="EmplService")
EntityManager em;

Bu aynı zamanda işlemlerinizi nasıl tasarladığınıza bağlı olarak birden fazla bağlamla karşılaşabileceğiniz anlamına gelir.

Genişletilmiş Kalıcı Bağlam

Durum bilgisi olan oturum çekirdeklerine sahip bir Java EE uygulamasında, fasulye kaldırılmak üzere işaretlenene kadar işlem yapmaktan hoşlanmadığınız için, bağlamın birden çok fasulye çağrısından kurtulmasını isteyebilirsiniz, değil mi? Bu durumlarda, genişletilmiş bir kalıcılık bağlamı kullanmanız gerekir. Bu durumda, kalıcılık bağlamı ilk ihtiyaç duyulduğunda oluşturulur, ancak durum bilgili fasulyeyi kaldırılmak üzere işaretleyene kadar geçersiz olmayacaktır.

@PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)

Bu, varlık yöneticisi örneğine bakılmaksızın, durum bilgisi olan oturum fasulye yöntemlerinin sonraki çağrılarında bu bean'e enjekte edilirse, her zaman aynı bağlama erişeceğinizden ve bu nedenle sonraki çağrıların bile aynı şeyi döndüreceğinden emin olabileceğiniz anlamına gelir. örnek, çünkü aynı bağlam.

Ayrıca, çekirdek çıkarılmak üzere işaretlenene veya siz onları manuel olarak temizleyene kadar değişiklikleriniz temizlenmeyecektir.

Uygulama Tarafından Yönetilen

Varlık yöneticisi fabrikanızı ve varlık yöneticinizi her zaman manuel olarak başlatabilirsiniz. Bir JSE uygulamasında tipik olarak yaptığınız şey bu, doğru mu?

Bu tür uygulamalar için genellikle JTA işlemleriyle ilgilenecek bir konteynere sahip değilsiniz, değil mi? Dolayısıyla, yerel kaynak işlemlerini kullanırsınız ve değişiklikleri manuel olarak gerçekleştirmek veya geri almaktan sorumlusunuz.

Bu tür bir uygulama için, varlık yöneticinizin örneğini oluşturduğunuzda, ona otomatik olarak bir bağlam eklenir.

Uygulamanıza bağlı olarak, yaşam döngüsü uygulamanın kendi yaşamına bağlı olan global bir varlık yöneticisi oluşturmaya karar verebilirsiniz. Bu, uygulamanın tüm ömrü boyunca tek bir varlık yöneticisidir. Bu durumlarda, bağlamınız varlık yöneticinizle birlikte oluşturulur ve yok edilir.

Veya uygulama kullanıcınızla her görüşme (yani işlem) başına bir varlık yöneticisi oluşturabilirsiniz. Bu durumda kapsam sizin tarafınızdan belirlenir, ancak yine de bağlamınız varlık yöneticinizle birlikte oluşturulacak ve yok edilecektir.


Harika yanıt, ancak bilmem gerekiyor: Bir oturum sırasında EntityManager'ı birkaç kez açıp kapatın, performansı yüksek mi? Yalnızca bir kez örnekleyin ve kapatın ya da her veritabanı işleminde onu örnekleyin / kullanın / kapatın, en iyi yaklaşım hangisidir? "değişir" tamam, ancak kullanım durumlarının çoğu için daha uygun bir kullanıma sahip olmalıdır ..
tomrlh

4
@tomurlh Endişelendiğim kadarıyla, yaratma maliyeti EntityManagerihmal edilebilir olmalıdır. Benim bakış açıma göre EntityManager, mevcut işlemin iş birimi ile ilgilenmek için sadece bir soyutlamadır . Her işlem için bir tane oluşturup yok etmenin tamamen iyi olduğuna inanıyorum. Şimdi, bunun başka etkileri de var, çünkü EntityManagervarlıklar için bir işlem önbelleği olarak sunucular ve bu nedenle iyi tanımlanmış bir işlem kapsamına sahip olmak ve varlıklarla düzgün bir şekilde ilgilenmek bu önbellekten yararlanabilir.
Edwin Dalorzo

EntityManager.close yöntemi, kalıcılık bağlamını serbest bırakmak için bir varlık yöneticisini kapatır, kalıcılık bağlamı nedir?
gstackoverflow

Bu aynı zamanda işlemlerinizi nasıl tasarladığınıza bağlı olarak birden fazla bağlamla karşılaşabileceğiniz anlamına gelir. Nasıl olduğunu açıklayabilir misin?
gstackoverflow
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.