Hibernate SessionFactoryとJPA EntityManagerFactoryの比較


251

Hibernateを初めて使用するので、Hibernate を作成するためにHibernateとSessionFactoryJPAのどちらを使用するかわかりません。 EntityManagerFactorySession

これら2つの違いは何ですか?それぞれを使用することの長所と短所は何ですか?


6
重複した質問に対するこの回答は本当に良いです。stackoverflow.com/questions/23445830/...
Sanghyunリー

回答:


365

とを優先EntityManagerFactoryEntityManagerます。これらはJPA標準で定義されています。

SessionFactoryそして、Session休止状態固有のものです。はEntityManager内部で休止状態セッションを呼び出します。また、で利用できない特定の機能が必要な場合はEntityManager、次を呼び出してセッションを取得できます。

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

2
@elpisu-実際にはお勧めできません。私は(少なくとも過去2年間は)公式ドキュメントのみを学習リソースとして使用しているため、他に信頼できるものはありません。しかし、ドキュメントは十分です。
Bozho

7
@Bozho遅いことは知っていますが、SessionFactoryとSessionを使用することの欠点は何ですか?JPAの使用が推奨される理由 ありがとう
Mickael Marrache

12
@MickaelMarracheはJava Enterprise標準であるため、JPAの使用はHibernate APIよりも優先されます。JPAを使用すると(Hibernate固有の機能を使用せずに制限することで)、アプリケーションの移植性が向上します。つまり、フレームワークもJPA標準に準拠している限り、アプリケーションへの変更を最小限に抑えて、別の永続性フレームワークに切り替えることができます。 。
ラースローファンデンホーク

2
エンタープライズ標準だからといって良いのでしょうか?私はそれを疑います。標準は通常、進化が遅く複雑です。実際のメリットについてはどうですか?TypedQueryを備えているため、JPAの方が優れています。
Bastian Voigt 2015年

1
取得するには、このアプローチであるSessionからではEntityManager同じ、SessionFactory.getCurrentSession()Sessionつまり、まだ作成されていない場合、新しく開きますか?マルチスレッド環境ではどのように機能しますか?
サルベシュ2018

32

これに加えて、getDelegate()メソッドをから呼び出してHibernateのセッションを取得することもできますEntityManager

例:

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

28
メモunwrap()ある好ましいことがgetDelegate()のJavaドキュメントによれば:のJavaEE 6のJavaEE 7
ryenus 2014

22

JPA2 EntityManagerAPIのSessionFactory方がモダンな感じがするので、私はJPA2 APIよりも好みます。簡単な例:

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;
}

EntityManagerは簡単にモックできるので、最初のものは見た目がきれいで、テストも簡単であることは明らかだと思います。


30
必要に応じて、コードを複雑にすることができます。return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
wst

どのように直接entityManagerを取得し、セッション
ファクトリー

21

EntityManagerFactoryアプローチを使用すると、@ PrePersist、@ PostPersist、@ PreUpdateなどのコールバックメソッドアノテーションを追加の設定なしで使用できます。

SessionFactoryの使用中に同様のコールバックを使用すると、追加の作業が必要になります。

関連するHibernateのドキュメントはここここにあります

関連するSOF質問Springフォーラムのディスカッション


21

SessionFactoryEntityManagerFactory

私が説明したようにHibernateユーザーガイド、HibernateはSessionFactoryJPAを拡張しEntityManagerFactory、次の図に示すように、:

JPAとHibernateの関係

したがって、SessionFactoryもJPA EntityManagerFactoryです。

どちらSessionFactoryEntityManagerFactoryエンティティのマッピング・メタデータが含まれていると、あなたが休止状態を作成することができますSessionEntityManager

SessionEntityManager

同じようにSessionFactoryEntityManagerFactory、HibernateはSessionJPAを拡張しますEntityManager。したがって、によって定義されたすべてのメソッドEntityManagerはHibernateで使用できますSession

Sessionそして`のEntityManagerが翻訳したエンティティの状態遷移を SELECT、INSERT、UPDATEのように、SQL文の中に、およびDELETE。

HibernateとJPAのブートストラップ

JPAまたはHibernateアプリケーションをブートストラップする場合、2つの選択肢があります。

  1. あなたは、Hibernateネイティブ機構を介してブートストラップ、および作成することができますSessionFactory経由でBootstrapServiceRegistryBuilder。Springを使用している場合LocalSessionFactoryBeanこのGitHubの例に示すように、Hibernateブートストラップはを介して行われます。
  2. または、クラスまたはEntityManagerFactoryを介してJPA を作成できます。Springを使用している場合、このGitHubの例で示されているように、JPAブートストラップはを介して行われます。PersistenceEntityManagerFactoryBuilderLocalContainerEntityManagerFactoryBean

JPAによるブートストラップが推奨されます。だとJPAがあるためFlushModeType.AUTO、従来よりもはるかに良い選択であるFlushMode.AUTO休憩を読み取り、あなたの-書き込み、ネイティブSQLクエリの一貫性が

JPAをHibernateにアンラップする

また、JPAを介してブートストラップEntityManagerFactoryし、@PersistenceUnitアノテーションを介してを挿入した場合:

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

メソッドSessionfactoryを使用して、基になるものに簡単にアクセスできますunwrap

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

JPAでも同じことができますEntityManager。アノテーションEntityManagerを介してを注入する場合@PersistenceContext

@PersistenceContext
private EntityManager entityManager;

メソッドSessionを使用して、基になるものに簡単にアクセスできますunwrap

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

結論

したがって、JPA を介してエンティティをフェッチするなど、JPAで利用できない一部のHibernate固有のメソッドにアクセスする場合はEntityManagerFactory、JPAを介してブートストラップし、およびを使用してEntityManager、それらを関連するHibernateインターフェースにアンラップする必要があります。


2

EntityManagerを使用することにより、コードは休止状態と密接に結合されなくなりました。しかし、このためには、使用法で使用する必要があります:

javax.persistence.EntityManager

の代わりに

org.hibernate.ejb.HibernateEntityManager

同様に、EntityManagerFactoryにはjavaxインターフェースを使用します。このようにして、コードは疎結合されます。hibernateよりも優れたJPA 2実装がある場合、切り替えは簡単です。極端な場合は、HibernateEntityManagerに型キャストできます。


2

EntityManagerFactoryは標準の実装であり、すべての実装で同じです。EclipseLinkなどの他のプロバイダー用にORMを移行する場合、トランザクションの処理方法に変更はありません。対照的に、hibernateのセッションファクトリを使用する場合、hibernate APIに関連付けられており、新しいベンダーに移行できません。


1

EntityManagerインターフェースは、HibernateのsessionFactoryに似ています。javax.persistanceパッケージのEntityManagerが、org.hibernate.Session / sessionFactoryパッケージのsessionおよびsessionFactory。

エンティティーマネージャーはJPA固有であり、セッション/セッションファクトリーは休止状態固有です。


あなたの答えは正しいですが、Sangyun Leeが彼のコメントで言及している答えと本質的に同じです...それで重複です。
RWC 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.