JPA

org.springframework.orm.jpa パッケージで利用可能な Spring JPA は、Hibernate との統合と同様の方法で Java Persistence API [Oracle] (英語) の包括的なサポートを提供すると同時に、追加機能を提供するための基礎となる実装を認識します。

Spring 環境での JPA セットアップの 3 つのオプション

Spring JPA サポートは、エンティティマネージャーを取得するためにアプリケーションで使用される JPA EntityManagerFactory をセットアップする 3 つの方法を提供します。

LocalEntityManagerFactoryBean を使用する

このオプションは、スタンドアロンアプリケーションや統合テストなどの単純なデプロイ環境でのみ使用できます。

LocalEntityManagerFactoryBean は、アプリケーションがデータアクセスに JPA のみを使用する単純なデプロイ環境に適した EntityManagerFactory を作成します。ファクトリ Bean は、JPA PersistenceProvider 自動検出メカニズム(JPA の Java SE ブートストラップによる)を使用し、ほとんどの場合、永続性ユニット名のみを指定する必要があります。次の XML の例は、このような Bean を構成します。

<beans>
	<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="myPersistenceUnit"/>
	</bean>
</beans>

この形式の JPA デプロイは、最も単純で最も制限されています。既存の JDBC DataSource Bean 定義を参照することはできず、グローバルトランザクションはサポートされていません。さらに、永続クラスのウィービング(バイトコード変換)はプロバイダー固有であり、多くの場合、起動時に特定の JVM エージェントを指定する必要があります。このオプションは、JPA 仕様が設計されているスタンドアロンアプリケーションおよびテスト環境にのみ十分です。

JNDI から EntityManagerFactory を取得する

Jakarta EE サーバーにデプロイするときに、このオプションを使用できます。カスタム JPA プロバイダーをサーバーにデプロイする方法に関するサーバーのドキュメントを確認し、サーバーのデフォルトとは異なるプロバイダーを許可します。

JNDI から EntityManagerFactory を取得する(たとえば、Jakarta EE 環境で)には、次の例に示すように、XML 構成を変更する必要があります。

<beans>
	<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>

このアクションは、標準の Jakarta EE ブートストラップを前提としています。Jakarta EE サーバーは、永続ユニット(実際には、アプリケーション jar 内の META-INF/persistence.xml ファイル)および Jakarta EE デプロイ記述子内の persistence-unit-ref エントリ(たとえば、web.xml)を自動検出し、それらの永続ユニットの環境命名コンテキストの場所を定義します。

このようなシナリオでは、永続クラスのウィービング(バイトコード変換)を含む永続ユニットデプロイ全体が Jakarta EE サーバーまでです。JDBC DataSource は、META-INF/persistence.xml ファイルの JNDI ロケーションを介して定義されます。EntityManager トランザクションは、サーバーの JTA サブシステムと統合されています。Spring は、取得した EntityManagerFactory を使用するだけで、依存性注入を介してアプリケーションオブジェクトに渡し、永続性ユニットのトランザクションを管理します(通常は JtaTransactionManager を使用)。

同じアプリケーションで複数の永続性ユニットを使用する場合、そのような JNDI 検索永続性ユニットの Bean 名は、アプリケーションが参照するために使用する永続性ユニット名と一致する必要があります(たとえば、@PersistenceUnit および @PersistenceContext アノテーション)。

LocalContainerEntityManagerFactoryBean を使用する

このオプションは、Spring ベースのアプリケーション環境で JPA の全機能に使用できます。これには、Tomcat などの Web コンテナー、スタンドアロンアプリケーション、高度な永続性要件を備えた統合テストが含まれます。

LocalContainerEntityManagerFactoryBean は EntityManagerFactory 構成を完全に制御し、きめ細かいカスタマイズが必要な環境に適しています。LocalContainerEntityManagerFactoryBean は、persistence.xml ファイル、提供された dataSourceLookup 戦略、指定された loadTimeWeaver に基づいて PersistenceUnitInfo インスタンスを作成します。JNDI の外部でカスタムデータソースを操作し、ウィービングプロセスを制御することができます。次の例は、LocalContainerEntityManagerFactoryBean の一般的な Bean 定義を示しています。

<beans>
	<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="someDataSource"/>
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
		</property>
	</bean>
</beans>

次の例は、典型的な persistence.xml ファイルを示しています。

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
	<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
		<mapping-file>META-INF/orm.xml</mapping-file>
		<exclude-unlisted-classes/>
	</persistence-unit>
</persistence>
<exclude-unlisted-classes/> ショートカットは、アノテーション付きエンティティクラスのスキャンが発生しないことを示しています。明示的な "true" 値(<exclude-unlisted-classes>true</exclude-unlisted-classes/>)もスキャンなしを意味します。<exclude-unlisted-classes>false</exclude-unlisted-classes/> はスキャンをトリガーします。ただし、エンティティクラススキャンを実行する場合は、exclude-unlisted-classes 要素を省略することをお勧めします。

LocalContainerEntityManagerFactoryBean の使用は、最も強力な JPA セットアップオプションであり、アプリケーション内での柔軟なローカル構成を可能にします。既存の JDBC DataSource へのリンクをサポートし、ローカルトランザクションとグローバルトランザクションの両方をサポートします。ただし、永続性プロバイダーがバイトコード変換を要求する場合、ウィービング対応のクラスローダーの可用性など、ランタイム環境にも要件が課されます。

このオプションは、Jakarta EE サーバーの組み込み JPA 機能と競合する場合があります。完全な Jakarta EE 環境では、JNDI から EntityManagerFactory を取得することを検討してください。または、LocalContainerEntityManagerFactoryBean 定義でカスタム persistenceXmlLocation を指定し(META-INF/my-persistence.xml など)、アプリケーション jar ファイルにその名前の記述子のみを含めます。Jakarta EE サーバーはデフォルトの META-INF/persistence.xml ファイルのみを探すため、このようなカスタム永続性ユニットを無視し、Spring 駆動の JPA セットアップとの競合を事前に回避します。(これは、たとえば Resin 3.1 に適用されます。)

ロード時のウィービングはいつ必要ですか?

すべての JPA プロバイダーが JVM エージェントを必要とするわけではありません。Hibernate はそうではない例です。プロバイダーがエージェントを必要としない場合、またはカスタムコンパイラーや Ant タスクを介してビルド時に拡張機能を適用するなど、他の代替手段がある場合は、ロード時ウィーバーを使用しないでください。

LoadTimeWeaver インターフェースは、環境が Web コンテナーであるかアプリケーションサーバーであるかに応じて、JPA ClassTransformer インスタンスを特定の方法でプラグインできる Spring 提供のクラスです。通常、エージェント (標準 Javadoc) を介した ClassTransformers のフックは効率的ではありません。エージェントは仮想マシン全体に対して動作し、ロードされているすべてのクラスをインスペクションします。これは通常、本番サーバー環境では望ましくありません。

Spring は、さまざまな環境に多数の LoadTimeWeaver 実装を提供し、ClassTransformer インスタンスを各 VM にではなく、各クラスローダーにのみ適用できるようにします。

LoadTimeWeaver の実装とそのセットアップに関する詳細なインサイトについては、AOP の章の Spring の構成を参照してください。汎用またはさまざまなプラットフォーム(Tomcat、JBoss、WebSphere など)にカスタマイズされています。

Spring の構成に従って、@EnableLoadTimeWeaving アノテーションまたは context:load-time-weaver XML 要素を使用して、コンテキスト全体の LoadTimeWeaver を構成できます。このようなグローバルウィーバーは、すべての JPA LocalContainerEntityManagerFactoryBean インスタンスによって自動的に取得されます。次の例は、ロード時ウィーバーをセットアップし、プラットフォームの自動検出(Tomcat のウィービング対応クラスローダーまたは Spring の JVM エージェントなど)を提供し、ウィーバーをすべてのウィーバー対応 Bean に自動伝播する推奨する方法を示しています。

<context:load-time-weaver/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	...
</bean>

ただし、次の例に示すように、必要に応じて、loadTimeWeaver プロパティを使用して専用のウィーバーを手動で指定できます。

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="loadTimeWeaver">
		<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
	</property>
</bean>

この手法を使用することにより、LTW がどのように構成されていても、エージェントを必要とせずに、計測に依存する JPA アプリケーションをターゲットプラットフォーム(たとえば、Tomcat)で実行できます。JPA トランスフォーマーはクラスローダーレベルでのみ適用され、相互に分離されているため、ホスティングアプリケーションが異なる JPA 実装に依存している場合、これは特に重要です。

複数の永続性ユニットの処理

複数の永続性ユニットの場所(たとえば、クラスパスのさまざまな JAR に格納されている)に依存するアプリケーションの場合、Spring は PersistenceUnitManager を提供して、主要リポジトリとして機能し、永続性ユニットの検出プロセスを回避します。デフォルトの実装では、複数の場所を指定できます。これらの場所は解析され、後で永続性ユニット名を通じて取得されます。(デフォルトでは、META-INF/persistence.xml ファイルのクラスパスが検索されます)次の例では、複数の場所を構成しています。

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
	<property name="persistenceXmlLocations">
		<list>
			<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
			<value>classpath:/my/package/**/custom-persistence.xml</value>
			<value>classpath*:META-INF/persistence.xml</value>
		</list>
	</property>
	<property name="dataSources">
		<map>
			<entry key="localDataSource" value-ref="local-db"/>
			<entry key="remoteDataSource" value-ref="remote-db"/>
		</map>
	</property>
	<!-- if no datasource is specified, use this one -->
	<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="persistenceUnitManager" ref="pum"/>
	<property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

デフォルトの実装では、PersistenceUnitInfo インスタンスを(JPA プロバイダーにフィードする前に)宣言的に(すべてのホストユニットに影響するプロパティを介して)またはプログラムにより(永続ユニットの選択を可能にする PersistenceUnitPostProcessor を介して)カスタマイズできます。PersistenceUnitManager が指定されていない場合、LocalContainerEntityManagerFactoryBean によって内部的に作成され使用されます。

バックグラウンドブートストラップ

LocalContainerEntityManagerFactoryBean は、次の例に示すように、bootstrapExecutor プロパティを介したバックグラウンドブートストラップをサポートしています。

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="bootstrapExecutor">
		<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
	</property>
</bean>

実際の JPA プロバイダーのブートストラップは、指定されたエグゼキューターに渡され、その後、並列で実行されて、アプリケーションのブートストラップスレッドに渡されます。公開された EntityManagerFactory プロキシは、他のアプリケーションコンポーネントに挿入でき、EntityManagerFactoryInfo 構成インスペクションに応答することさえできます。ただし、実際の JPA プロバイダーが他のコンポーネント(たとえば、createEntityManager の呼び出し)によってアクセスされると、それらの呼び出しは、バックグラウンドのブートストラップが完了するまでブロックされます。特に、Spring Data JPA を使用する場合は、リポジトリの遅延ブートストラップも必ず設定してください。

JPA に基づいた DAO の実装: EntityManagerFactory および EntityManager

EntityManagerFactory インスタンスはスレッドセーフですが、EntityManager インスタンスはそうではありません。挿入された JPA EntityManager は、JPA 仕様で定義されているように、アプリケーションサーバーの JNDI 環境からフェッチされた EntityManager のように動作します。すべての呼び出しを現在のトランザクション EntityManager に委譲します(存在する場合)。それ以外の場合、操作ごとに新しく作成された EntityManager にフォールバックし、事実上、その使用をスレッドセーフにします。

注入された EntityManagerFactory または EntityManager を使用することによって、Spring の依存関係なしに単純な JPA に対してコードを書くことができます。Spring は、PersistenceAnnotationBeanPostProcessor が有効になっている場合、@PersistenceUnit および @PersistenceContext アノテーションをフィールドレベルとメソッドレベルの両方で認識できます。次の例は、@PersistenceUnit アノテーションを使用する単純な JPA DAO 実装を示しています。

  • Java

  • Kotlin

public class ProductDaoImpl implements ProductDao {

	private EntityManagerFactory emf;

	@PersistenceUnit
	public void setEntityManagerFactory(EntityManagerFactory emf) {
		this.emf = emf;
	}

	public Collection loadProductsByCategory(String category) {
		EntityManager em = this.emf.createEntityManager();
		try {
			Query query = em.createQuery("from Product as p where p.category = ?1");
			query.setParameter(1, category);
			return query.getResultList();
		}
		finally {
			if (em != null) {
				em.close();
			}
		}
	}
}
class ProductDaoImpl : ProductDao {

	private lateinit var emf: EntityManagerFactory

	@PersistenceUnit
	fun setEntityManagerFactory(emf: EntityManagerFactory) {
		this.emf = emf
	}

	fun loadProductsByCategory(category: String): Collection<*> {
		val em = this.emf.createEntityManager()
		val query = em.createQuery("from Product as p where p.category = ?1");
		query.setParameter(1, category);
		return query.resultList;
	}
}

上記の DAO は Spring に依存せず、Spring アプリケーションコンテキストにうまく適合します。さらに、次の Bean 定義の例が示すように、DAO はアノテーションを利用してデフォルトの EntityManagerFactory の挿入を要求します。

<beans>

	<!-- bean post-processor for JPA annotations -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

PersistenceAnnotationBeanPostProcessor を明示的に定義する代わりに、アプリケーションコンテキスト設定で Spring context:annotation-config XML 要素を使用することを検討してください。これにより、CommonAnnotationBeanPostProcessor などを含むすべての Spring 標準ポストプロセッサーがアノテーションベースの構成に自動的に登録されます。

次の例を考えてみましょう。

<beans>

	<!-- post-processors for all standard config annotations -->
	<context:annotation-config/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

このような DAO の主な問題は、ファクトリを通じて常に新しい EntityManager を作成することです。これを回避するには、トランザクション EntityManager (実際のトランザクション EntityManager の共有のスレッドセーフプロキシであるため、「共有 EntityManager」とも呼ばれます)をファクトリの代わりに挿入するようにリクエストします。次の例は、そのメソッドを示しています。

  • Java

  • Kotlin

public class ProductDaoImpl implements ProductDao {

	@PersistenceContext
	private EntityManager em;

	public Collection loadProductsByCategory(String category) {
		Query query = em.createQuery("from Product as p where p.category = :category");
		query.setParameter("category", category);
		return query.getResultList();
	}
}
class ProductDaoImpl : ProductDao {

	@PersistenceContext
	private lateinit var em: EntityManager

	fun loadProductsByCategory(category: String): Collection<*> {
		val query = em.createQuery("from Product as p where p.category = :category")
		query.setParameter("category", category)
		return query.resultList
	}
}

@PersistenceContext アノテーションには、type と呼ばれるオプション属性があり、デフォルトは PersistenceContextType.TRANSACTION です。このデフォルトを使用して、共有 EntityManager プロキシを受信できます。代替の PersistenceContextType.EXTENDED は、まったく異なる問題です。これにより、いわゆる拡張 EntityManager が生成されます。これはスレッドセーフではないため、Spring 管理のシングルトン Bean など、同時にアクセスされるコンポーネントで使用しないでください。拡張 EntityManager インスタンスは、たとえばセッションに存在するステートフルコンポーネントでのみ使用されることになっています。EntityManager のライフサイクルは現在のトランザクションに関連付けられておらず、アプリケーションに完全に依存しています。

メソッドおよびフィールドレベルの注入

クラス内のフィールドまたはメソッドに依存性注入(@PersistenceUnit や @PersistenceContext など)を示すアノテーションを適用できます。「メソッドレベルの注入」および「フィールドレベルの注入」という表現になります。フィールドレベルのアノテーションは簡潔で使いやすく、メソッドレベルのアノテーションは注入された依存関係のさらなる処理を可能にします。どちらの場合も、メンバーの可視性(パブリック、保護、プライベート)は重要ではありません。

クラスレベルのアノテーションはどうですか?

Jakarta EE プラットフォームでは、リソースの注入ではなく、依存関係の宣言に使用されます。

注入された EntityManager は Spring によって管理されます (進行中のトランザクションを認識します)。新しい DAO 実装では EntityManagerFactory ではなく EntityManager のメソッドレベルの注入が使用されていますが、アノテーションの使用による Bean 定義の変更は必要ありません。

この DAO スタイルの主な利点は、Java Persistence API のみに依存することです。Spring クラスのインポートは必要ありません。さらに、JPA アノテーションが理解されると、注入は Spring コンテナーによって自動的に適用されます。これは、非侵襲性の観点から魅力的であり、JPA 開発者にとってより自然に感じることができます。

@Autowired に基づく DAO の実装 (通常はコンストラクターベースのインジェクションを使用します)

@PersistenceUnit および @PersistenceContext はメソッドとフィールドでのみ宣言できます。コンストラクターや他の @Autowired インジェクションポイントを介して JPA リソースを提供する場合はどうすればよいでしょうか ?

EntityManagerFactory は、ターゲットが Bean として定義されている限り、コンストラクターと @Autowired フィールド / メソッドを介して簡単に注入できます。LocalContainerEntityManagerFactoryBean 経由。インジェクションポイントは、型ごとに元の EntityManagerFactory 定義とそのまま一致します。

ただし、@PersistenceContext スタイルの共有 EntityManager 参照は、そのままでは通常の依存性注入には使用できません。@Autowired で必要とされる型ベースのマッチングに使用できるようにするには、EntityManagerFactory 定義のコンパニオンとして SharedEntityManagerBean を定義することを検討してください。

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	...
</bean>

<bean id="em" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
	<property name="entityManagerFactory" ref="emf"/>
</bean>

あるいは、SharedEntityManagerCreator に基づいて @Bean メソッドを定義することもできます。

@Bean("em")
public static EntityManager sharedEntityManager(EntityManagerFactory emf) {
	return SharedEntityManagerCreator.createSharedEntityManager(emf);
}

複数の永続化ユニットの場合、各 EntityManagerFactory 定義には、対応する EntityManager Bean 定義を伴う必要があります。理想的には、@Autowired @Qualifier("…​") を介して永続化ユニットを区別するために、個別の EntityManagerFactory 定義と一致する修飾子を伴う必要があります。

Spring 駆動の JPA トランザクション

Spring の宣言的なトランザクションサポートの詳細を網羅するために、まだ読んでいない場合は宣言的トランザクション管理を読むことを強くお勧めします。

JPA に推奨される戦略は、JPA のネイティブトランザクションサポートを介したローカルトランザクションです。Spring の JpaTransactionManager は、JTA トランザクションコーディネーターや XA 対応リソースを必要とせずに、通常の JDBC 接続プールに対して、ローカル JDBC トランザクションで知られる多くの機能 (トランザクション固有の分離レベルやリソースレベルの読み取り専用最適化など) を提供します。

Spring JPA では、登録された JpaDialect が基礎となる JDBC Connection の取得をサポートしている場合、構成された JpaTransactionManager が同じ DataSource にアクセスする JDBC アクセスコードに JPA トランザクションを公開できるようになります。Spring は、EclipseLink および Hibernate JPA 実装のダイアレクトを提供します。JpaDialect の詳細については、次のセクションを参照してください。

実際のリソース接続の JTA スタイルの遅延取得のために、Spring はターゲット接続プールに対応する DataSource プロキシクラスを提供します。LazyConnectionDataSourceProxy (Javadoc) を参照してください。これは、データベースにアクセスするのではなく、ローカルキャッシュから処理できることが多い JPA 読み取り専用トランザクションに特に役立ちます。

JpaDialect および JpaVendorAdapter を理解する

高度な機能として、JpaTransactionManager および AbstractEntityManagerFactoryBean のサブクラスにより、カスタム JpaDialect を jpaDialect Bean プロパティに渡すことができます。JpaDialect の実装により、通常はベンダー固有の方法で、Spring でサポートされる次の高度な機能を有効にできます。

  • 特定のトランザクションセマンティクスの適用 (カスタム分離レベルやトランザクションタイムアウトなど)

  • トランザクション JDBC Connection の取得 (JDBC ベースの DAO への露出用)

  • PersistenceException から Spring の DataAccessException への高度な変換

これは、特別なトランザクションセマンティクスおよび例外の高度な変換に特に役立ちます。デフォルトの実装(DefaultJpaDialect)は特別な機能を提供しません。前述の機能が必要な場合は、適切なダイアレクトを指定する必要があります。

主に Spring のフル機能の LocalContainerEntityManagerFactoryBean セットアップのためのさらに広範なプロバイダー適応機能として、JpaVendorAdapter は JpaDialect の機能を他のプロバイダー固有のデフォルトと組み合わせます。HibernateJpaVendorAdapter または EclipseLinkJpaVendorAdapter を指定することは、それぞれ Hibernate または EclipseLink 用に EntityManagerFactory セットアップを自動構成する最も便利な方法です。これらのプロバイダーアダプターは、主に Spring 駆動のトランザクション管理で使用するために設計されていることに注意してください(つまり、JpaTransactionManager で使用するため)。

操作の詳細と、Spring の JPA サポート内での使用方法については、JpaDialect (Javadoc) および JpaVendorAdapter javadoc を参照してください。

JTA Transaction Management を使用した JPA のセットアップ

JpaTransactionManager の代替として、Spring は、Jakarta EE 環境または Atomikos などのスタンドアロンのトランザクションコーディネーターと JTA を介したマルチリソーストランザクションの調整も可能にします。JpaTransactionManager の代わりに Spring の JtaTransactionManager を選択する以外に、さらにいくつかの手順を実行する必要があります。

  • 基盤となる JDBC 接続プールは XA 対応であり、トランザクションコーディネーターと統合されている必要があります。これは通常、Jakarta EE 環境では簡単であり、JNDI を介して異なる種類の DataSource を公開します。詳細については、アプリケーションサーバーのドキュメントを参照してください。同様に、スタンドアロンのトランザクションコーディネーターには、通常、特別な XA 統合 DataSource バリアントが付属しています。もう一度、そのドキュメントを確認してください。

  • JPA EntityManagerFactory セットアップは、JTA 用に構成する必要があります。これはプロバイダー固有であり、通常は LocalContainerEntityManagerFactoryBean で jpaProperties として指定される特別なプロパティを使用します。Hibernate の場合、これらのプロパティはバージョン固有ですらあります。詳細については、Hibernate のドキュメントを参照してください。

  • Spring の HibernateJpaVendorAdapter は、接続解放モード on-close などの特定の Spring 指向のデフォルトを適用します。これは、Hibernate 5.0 では Hibernate 自身のデフォルトと一致しますが、Hibernate 5.1+ ではこれ以上一致しません。JTA セットアップの場合、永続性ユニットのトランザクション型を "JTA" として宣言してください。または、Hibernate 5.2 の hibernate.connection.handling_mode プロパティを DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT に設定して、Hibernate 自体のデフォルトを復元します。関連する注記については、Hibernate を使用した偽のアプリケーションサーバー警告を参照してください。

  • または、アプリケーションサーバー自体から EntityManagerFactory を取得することを検討してください(つまり、ローカルで宣言された LocalContainerEntityManagerFactoryBean の代わりに JNDI ルックアップを使用して)。サーバーが提供する EntityManagerFactory では、サーバー構成で特別な定義が必要になる場合があります(デプロイの移植性が低下します)が、サーバーの JTA 環境用にセットアップされます。

JPA 相互作用のためのネイティブ Hibernate セットアップおよびネイティブ Hibernate トランザクション

HibernateTransactionManager と組み合わせたネイティブ LocalSessionFactoryBean セットアップにより、@PersistenceContext およびその他の JPA アクセスコードとの対話が可能になります。Hibernate SessionFactory は現在 JPA の EntityManagerFactory インターフェースをネイティブに実装しており、Hibernate Session ハンドルはネイティブに JPA EntityManager です。Spring の JPA サポート機能は、ネイティブ Hibernate セッションを自動的に検出します。

このようなネイティブ Hibernate セットアップは、多くのシナリオで標準の JPA LocalContainerEntityManagerFactoryBean と JpaTransactionManager の組み合わせの代替として機能し、同じローカルトランザクション内で @PersistenceContext EntityManager の隣の SessionFactory.getCurrentSession() (および HibernateTemplate)との相互作用を可能にします。このようなセットアップは、JPA ブートストラップ契約に制約されないため、Hibernate の統合を強化し、構成の柔軟性を高めます。

Spring のネイティブ Hibernate セットアップはさらに多くの機能(たとえば、カスタム Hibernate Integrator セットアップ、Hibernate 5.3 Bean コンテナー統合、読み取り専用トランザクションの強力な最適化など)を提供するため、このようなシナリオでは HibernateJpaVendorAdapter 構成は必要ありません。最後に重要なことですが、LocalSessionFactoryBuilder を介してネイティブ Hibernate セットアップを表現し、@Bean スタイルの構成とシームレスに統合することもできます(FactoryBean は含まれません)。

LocalSessionFactoryBean および LocalSessionFactoryBuilder は、JPA LocalContainerEntityManagerFactoryBean と同様に、バックグラウンドブートストラップをサポートしています。はじめにバックグラウンドブートストラップを参照してください。

LocalSessionFactoryBean では、これは bootstrapExecutor プロパティを通じて利用できます。プログラムによる LocalSessionFactoryBuilder では、オーバーロードされた buildSessionFactory メソッドはブートストラップエグゼキューター引数を取ります。