Hazırda Bekletme Oturumu Fabrikası ve JPA EntityManagerFactory Karşılaştırması


251

Hazırda Bekletme konusunda yeniyim ve Hazırda Bekletme oluşturmak için Hazırda Beklet SessionFactoryveya JPA kullanıp kullanmadığından emin değilim . EntityManagerFactorySession

Bu ikisi arasındaki fark nedir? Bunların her birini kullanmanın avantajları ve dezavantajları nelerdir?


6
Yinelenen bir soru üzerine bu cevap gerçekten çok iyi. stackoverflow.com/questions/23445830/…
Sanghyun Lee

Yanıtlar:


365

Tercih EntityManagerFactoryve EntityManager. Bunlar JPA standardı tarafından tanımlanır.

SessionFactoryve Sessionhazırda bekletme özelliğine sahiptir. EntityManagerKaputun altında hazırda oturumuna çağırır. Ve içinde bulunmayan bazı belirli özelliklere ihtiyacınız varsa EntityManager, şu numarayı arayarak oturumu edinebilirsiniz:

Session session = entityManager.unwrap(Session.class);

2
@elpisu - Aslında tavsiye edemem. Sadece resmi belgeleri bir öğrenme kaynağı olarak kullanıyorum (en azından son 2 yılda), bu yüzden güvenilir başka bir şey bilmiyorum. Ama dokümanlar yeterince iyi.
Bozho

7
@Bozho Geç olduğunu biliyorum ama SessionFactory ve Session kullanmanın sakıncaları nelerdir? Neden JPA kullanımı tercih edilir? Teşekkürler
Mickael Marrache

12
@MickaelMarrache JPA kullanımı Hazırda Bekletme API'sine göre tercih edilecektir, çünkü bir Java Enterprise standardıdır. Hazırda Bekleme Özel özellikleri kullanmadan JPA kullanmak (ve kendinizi Hibernate'e özgü özellikler kullanmadan kısıtlamak), uygulama taşınabilirliğini artırır; yani, bu çerçeve JPA standardına uyduğu sürece uygulamanızda minimum değişikliklerle farklı bir kalıcılık çerçevesine geçme seçeneğiniz vardır. .
László van den Hoek

2
Kurumsal bir standart olduğu için daha mı iyi? Bundan şüpheliyim. Standartlar genellikle yavaş gelişir ve karmaşıktır. Gerçek hayattaki bazı faydalara ne dersiniz? JPA daha iyi çünkü TypedQuery var, her yerde daktiloda olmanızı engelliyor.
Bastian Voigt

1
Almak için bu yaklaşım mı Sessiondan EntityManageraynı, SessionFactory.getCurrentSession()? Yani, Sessionhenüz oluşturulmamışsa yeni açılacak mı? Çok iş parçacıklı ortamda nasıl çalışır?
Sarvesh

32

Ben de bu getDelegate()yöntemi arayarak Hibernate oturumu alabilirsiniz eklemek istiyorum EntityManager.

örn:

Session session = (Session) entityManager.getDelegate();

28
Not unwrap()olan tercih edilecek üzerinde getDelegate()java dokümanlar göre JavaEE 6 ve JavaEE 7 .
ryenus

22

JPA2 EntityManagerAPI'sini tercih ediyorum SessionFactory, çünkü daha modern geliyor. Basit bir örnek:

JPA:

@PersistenceContext
EntityManager entityManager;

public List<MyEntity> findSomeApples() {
  return entityManager
     .createQuery("from MyEntity where apples=7", MyEntity.class)
     .getResultList();
}

SessionFactory:

@Autowired
SessionFactory sessionFactory;

public List<MyEntity> findSomeApples() {
  Session session = sessionFactory.getCurrentSession();
  List<?> result = session.createQuery("from MyEntity where apples=7")
      .list();
  @SuppressWarnings("unchecked")
  List<MyEntity> resultCasted = (List<MyEntity>) result;
  return resultCasted;
}

İlkinin daha temiz göründüğünü ve test etmenin daha kolay olduğunu düşünüyorum çünkü EntityManager kolayca alay edilebilir.


30
İsterseniz herhangi bir kodu karmaşık hale getirebilirsiniz. return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
WST

EntityManager'ı doğrudan nasıl aldınız ve oturumu almak için sessionfactory'yi kullanmak zorunda olduğunuzu gösteriyorsunuz ..: D
JavaLearner


21

SessionFactory vs. EntityManagerFactory

Hazırda Bekletme Kullanıcı Kılavuzu'nda açıkladığım gibi, Hazırda Bekletme aşağıdaki diyagramda gösterildiği gibi SessionFactoryJPA'yı genişletir EntityManagerFactory:

JPA ve Hazırda Bekletme ilişkisi

Yani, SessionFactoryaynı zamanda bir JPAEntityManagerFactory .

Hem ve SessionFactoryhem de EntityManagerFactoryvarlık eşleme meta verilerini içerir ve Hazırda Beklet SessionveyaEntityManager .

Session vs. EntityManager

Tıpkı SessionFactoryve EntityManagerFactorygibi, Hibernate Sessionde JPA'yı genişletir EntityManager. Yani, tarafından tanımlanan tüm yöntemler EntityManagerHazırda Bekletme modunda kullanılabilirSession .

Ve SessionEntityManager varlık durumu geçişlerini SELECT, INSERT, UPDATE ve DELETE gibi SQL deyimlerine çevirir .

Hazırda Beklet ve JPA önyükleme

Bir JPA veya Hazırda Bekletme uygulamasını önyüklerken iki seçeneğiniz vardır:

  1. Hazırda Beklet yerel mekanizması aracılığıyla önyükleme yapabilir SessionFactoryve BootstrapServiceRegistryBuilder. Spring kullanıyorsanız, Hibernate bootstrap, bu GitHub örneğindeLocalSessionFactoryBean gösterildiği gibi the aracılığıyla yapılır .
  2. Veya sınıf ya da EntityManagerFactoryaracılığıyla bir JPA oluşturabilirsiniz . Spring kullanıyorsanız, JPA önyükleme işlemi bu GitHub örneğinde gösterildiği gibi the aracılığıyla yapılır .PersistenceEntityManagerFactoryBuilderLocalContainerEntityManagerFactoryBean

JPA ile önyükleme tercih edilecektir. JPA Çünkü FlushModeType.AUTOmirası çok daha iyi bir seçimdir FlushMode.AUTO, sonları okuma-senin-yazar yerel SQL sorguları için tutarlılık .

Hazırda Bekletme modunu açmak için JPA'yı açma

Ayrıca, JPA ile önyükleme yaparsanız EntityManagerFactoryve @PersistenceUnitek açıklama yoluyla enjekte ettiyseniz :

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

Yöntemi Sessionfactorykullanarak temel bilgilere kolayca erişebilirsiniz unwrap:

SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);

Aynı şey JPA için de yapılabilir EntityManager. Ek açıklama EntityManageryoluyla enjekte ederseniz @PersistenceContext:

@PersistenceContext
private EntityManager entityManager;

Yöntemi Sessionkullanarak temel bilgilere kolayca erişebilirsiniz unwrap:

Session session = entityManager.unwrap(Session.class);

Sonuç

Bu nedenle, JPA üzerinden önyükleme yapmalı EntityManagerFactoryve EntityManagerve işlevlerini kullanmalı ve yalnızca varlığın doğal tanımlayıcısı aracılığıyla getirilmesi gibi JPA'da bulunmayan Hazırda Bekleme özgü yöntemlere erişmek istediğinizde bunları ilişkili Hazırda Bekletme arabirimlerine açmalısınız .


2

EntityManager kullanıldığında, kod artık hazırda bekletme moduyla sıkıca birleştirilmez. Ancak bunun için, kullanımda kullanmalıyız:

javax.persistence.EntityManager

onun yerine

org.hibernate.ejb.HibernateEntityManager

Benzer şekilde, EntityManagerFactory için javax arabirimini kullanın. Bu şekilde, kod gevşek bir şekilde bağlanmıştır. Hazırda bekletme modundan daha iyi bir JPA 2 uygulaması varsa, geçiş yapmak kolay olacaktır. Aşırı durumda, HibernateEntityManager'a cast yazabiliriz.


2

EntityManagerFactory standart bir uygulamadır, tüm uygulamalarda aynıdır. ORM'nizi EclipseLink gibi başka bir sağlayıcıya geçirirseniz, işlemin ele alınmasına ilişkin yaklaşımda herhangi bir değişiklik olmayacaktır. Buna karşılık, hazırda bekletme modunun oturum fabrikasını kullanırsanız, API'ları hazırda bekletme modlarına bağlanır ve yeni satıcıya taşınamaz.


1

EntityManager arayüzü, hazırda bekletme modunda sessionFactory öğesine benzer. EntityManager javax.persistance paketi altında ancak org.hibernate.Session / sessionFactory paketi altında session ve sessionFactory altında.

Varlık yöneticisi JPA'ya özgü ve session / sessionFactory hazırda bekletme moduna özeldir.


Cevabınız doğru, ama aslında Sangyun Lee'nin yorumlarında bahsettiği cevapla aynı ... yani bir kopya.
RWC
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.