web-dev-qa-db-ja.com

LocalContainerEntityManagerFactoryBeanとLocalEntityManagerFactoryBeanの違いは何ですか?

Spring FrameworkのLocalContainerEntityManagerFactoryBeanLocalEntityManagerFactoryBeanの違いは何ですか?

40
BlueSky

基本的にJPA仕様2種類のエンティティマネージャを定義します。彼らです :

i)Application-Managed:アプリケーション管理エンティティマネージャーは、「エンティティマネージャーはアプリケーション(つまり、コード)によってのみ作成および管理される」ことを意味します。

ii)コンテナ管理:コンテナ管理のエンティティマネージャは、「エンティティマネージャは単にJ2EEコンテナによって作成および管理されます(つまり、コードは直接管理せず、エンティティマネージャはコンテナによって作成および管理されます。コードは、JNDIを使用するなどの方法でEMを取得します。

注:作成および管理(上記)は、「エンティティマネージャーをトランザクションで開く、閉じる、関与する」ことを意味します。

LocalContainerEntityManagerFactoryBean-コンテナ管理
LocalEntityManagerFactoryBean-アプリケーション管理

ビッグノート:スプリングベースのアプリケーションの場合、の差はそれほど大きくありませんSpringは役割のみを果たします(as container設定した場合LocalContainerEntityManagerFactoryBeanおよびapplicationとして構成する場合LocalEntityManagerFactoryBean

39
Prashanth

ドキュメントはそれをすべて言います:

LocalContainerEntityManagerFactoryBean -リンクから:JPAの標準に従ってJPA EntityManagerFactoryを作成するFactoryBeancontainerbootstrap契約。

LocalEntityManagerFactoryBean -リンクから:JPAの標準に従ってJPA EntityManagerFactoryを作成するFactoryBeanstandalonebootstrap契約。

基本的に、唯一の違いは、JPA EntityManagerFactoryの作成方法にあります。

17

LocalEntityManagerFactoryBean

最も単純で最も制限されています。既存のJDBC DataSource Bean定義を参照することはできず、グローバルトランザクションはサポートされていません。

LocalContainerEntityManagerFactoryBean

は最も強力なJPAセットアップオプションであり、アプリケーション内で柔軟なローカル構成を可能にします。既存のJDBCデータソースへのリンクをサポートし、ローカルトランザクションとグローバルトランザクションの両方をサポートします

REF:spring-framework-reference.pdf "Spring 3"

16

LocalEntityManagerFactoryBeanは、アプリケーションが管理するEntityManagerFactoryを生成します。

LocalContainerEntityManagerFactoryBeanは、コンテナ管理のEntityManagerFactoryを生成します。

Ref:Spring In Action-Craig Walls

10
Chandana

JPA仕様では、2種類のエンティティーマネージャーを定義しています。

  • Application-managed —アプリケーションがエンティティマネージャーファクトリに直接要求すると、エンティティマネージャーが作成されます。アプリケーション管理のエンティティーマネージャーでは、アプリケーションはエンティティーマネージャーを開いたり閉じたりし、トランザクションにエンティティーマネージャーを関与させます。このタイプのエンティティマネージャーは、Java EEコンテナーで実行されないスタンドアロンアプリケーションでの使用に最適です。

  • Container-managed-エンティティマネージャーはJava EEコンテナーによって作成および管理されます。アプリケーションはエンティティマネージャーファクトリとまったく対話しません。代わりに、エンティティマネージャーは注入またはJNDIから直接取得されます。コンテナは、エンティティマネージャファクトリの構成を担当します。このタイプのエンティティマネージャは、Java何らかの制御を維持する必要があるEEコンテナによる使用に最適です。 persistence.xmlで指定されているものを超えたJPA構成。

アプリケーション管理EntityManagersは、PersistenceProviderのcreateEntityManagerFactory()メソッドを呼び出して取得したEntityManagerFactoryによって作成されます。一方、container-managed EntityManagerFactorysは、PersistenceProviderのcreateContainerEntityManagerfactory() methodを通じて取得されます。

エンティティマネージャーファクトリの各フレーバーは、対応するSpringファクトリBeanによって生成されます。

  • LocalEntityManagerFactoryBeanは、アプリケーションが管理するEntity- ManagerFactoryを生成します。

  • LocalContainerEntityManagerFactoryBeanはコンテナ管理のEntityManagerFactoryを生成します

アプリケーション管理のEntityManagerFactoryとコンテナ管理のEntityManagerFactoryの間で行われた選択は、Springベースのアプリケーションに対して完全に透過的であることを指摘することが重要です。 SpringとJPAを使用している場合、どちらの形式のEntityManagerFactoryを処理する場合の複雑な詳細は隠され、データアクセスコードはその本来の目的であるデータアクセスに集中できます。

application-managedcontainer-managedの唯一の本当の違いは、Springに関する限り、エンティティマネージャーファクトリは、Springアプリケーションコンテキストでそれぞれがどのように構成されるかです。

6
PAA
  • LocalEntityManagerFactoryBeanとLocalContainerEntityManagerFactoryBeanの両方の実装は、org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImplからEntityManagerFactory参照を返します。
  • SpringにJTAの使用を明示的に要求しない限り、各実装はresource_localトランザクションを使用します。
  • 2つの実装の主な違いは、LocalContainerEntityManagerFactoryBeanがプログラムで設定する永続性ユニット(データソースとpackageToScan)を提供し、事前定義された名前の永続性を使用する必要があるLocalEntityManagerFactoryBeanと比較して、persistence.xmlファイルの場所をオーバーライドできるという点でより柔軟です。 .xml

両方がデフォルトでresource_localを使用している場合、LocalContainerEntityManagerFactoryBeanがコンテナ管理のトランザクションを使用しており、他のアプリケーションがアプリケーション管理のトランザクションを使用していることは大概のことです。

依存関係注入コンテナーの外でJPAを使用する場合、トランザクションは開発者がプロ​​グラムで処理する必要があります。 Spring依存関係注入コンテナー内でJPAを使用する場合、Springコンテナーで処理できます。

LocalContainerEntityManagerFactoryBeanの使用例

public class DataConfig {
    @Bean
    LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        //LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        LocalContainerEntityManagerFactoryBean lfb = new LocalContainerEntityManagerFactoryBean();
        lfb.setDataSource(dataSource());
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setPackagesToScan("com.javasampleapproach.h2database.model");
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}
@Component
public class PostRepository {
  @Autowired
    EntityManagerFactory emf;
  }
  public void create(){
      EntityManager em = emf.createEntityManager();
      Post post = new Post("First post");
      em.getTransaction().begin();
      em.persist(post);
      em.getTransaction().commit();
  }
}

LocalEntityManagerFactoryBeanのエラー

Java.lang.IllegalStateException:共有EntityManagerでのトランザクションの作成は許可されていません-代わりにSpringトランザクションまたはEJB CMTを使用してください

public class DataConfig {
    @Bean
    LocalEntityManagerFactoryBean entityManagerFactory() {
        LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}

@Component
    public class PostRepository {
      @Autowired
      EntityManager em;

      public void create(){
          EntityManager em = emf.createEntityManager();
          Post post = new Post("First post");
          em.getTransaction().begin();
          em.persist(post);
          em.getTransaction().commit();
      }
    }
<persistence-unit name="localEntity">
</persistence-unit>

LocalEntityManagerFactoryBeanを使用した作業コード

LocalEntityManagerFactoryBeanの場合はコンテナ管理のような春管理トランザクション

public class DataConfig {
    @Bean
    LocalEntityManagerFactoryBean entityManagerFactory() {
        LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}

@Component
public class PostRepository {
  @Autowired
  EntityManagerFactory emf;

  @Transactional
  public void create() {
    Post post = new Post("First post");
    em.persist(post);
  }
}

<persistence-unit name="localEntity">
</persistence-unit>

どちらの実装もコンテナー管理トランザクションで使用できます。何らかの修正が必要な場合は、これを修正してください。

0
Pushpendra