Spring FrameworkのLocalContainerEntityManagerFactoryBeanとLocalEntityManagerFactoryBeanの違いは何ですか?
基本的にJPA仕様は2種類のエンティティマネージャを定義します。彼らです :
i)Application-Managed:アプリケーション管理エンティティマネージャーは、「エンティティマネージャーはアプリケーション(つまり、コード)によってのみ作成および管理される」ことを意味します。
ii)コンテナ管理:コンテナ管理のエンティティマネージャは、「エンティティマネージャは単にJ2EEコンテナによって作成および管理されます(つまり、コードは直接管理せず、エンティティマネージャはコンテナによって作成および管理されます。コードは、JNDIを使用するなどの方法でEMを取得します。
注:作成および管理(上記)は、「エンティティマネージャーをトランザクションで開く、閉じる、関与する」ことを意味します。
LocalContainerEntityManagerFactoryBean-コンテナ管理
LocalEntityManagerFactoryBean-アプリケーション管理
ビッグノート:スプリングベースのアプリケーションの場合、の差はそれほど大きくありません。 Springは役割のみを果たします(as container設定した場合LocalContainerEntityManagerFactoryBeanおよびapplicationとして構成する場合LocalEntityManagerFactoryBean)
ドキュメントはそれをすべて言います:
LocalContainerEntityManagerFactoryBean -リンクから:JPAの標準に従ってJPA EntityManagerFactoryを作成するFactoryBeancontainerbootstrap契約。
LocalEntityManagerFactoryBean -リンクから:JPAの標準に従ってJPA EntityManagerFactoryを作成するFactoryBeanstandalonebootstrap契約。
基本的に、唯一の違いは、JPA EntityManagerFactory
の作成方法にあります。
LocalEntityManagerFactoryBean
最も単純で最も制限されています。既存のJDBC DataSource Bean定義を参照することはできず、グローバルトランザクションはサポートされていません。
LocalContainerEntityManagerFactoryBean
は最も強力なJPAセットアップオプションであり、アプリケーション内で柔軟なローカル構成を可能にします。既存のJDBCデータソースへのリンクをサポートし、ローカルトランザクションとグローバルトランザクションの両方をサポートします
REF:spring-framework-reference.pdf "Spring 3"
LocalEntityManagerFactoryBeanは、アプリケーションが管理するEntityManagerFactoryを生成します。
LocalContainerEntityManagerFactoryBeanは、コンテナ管理のEntityManagerFactoryを生成します。
Ref:Spring In Action-Craig Walls
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-managedとcontainer-managedの唯一の本当の違いは、Springに関する限り、エンティティマネージャーファクトリは、Springアプリケーションコンテキストでそれぞれがどのように構成されるかです。
両方がデフォルトで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>
どちらの実装もコンテナー管理トランザクションで使用できます。何らかの修正が必要な場合は、これを修正してください。