Spring Bean コンテナーを使用せずに、DAO プロキシー (別名リポジトリー) を生成できるように、Spring Data JPA オブジェクトを手動で接続しようとしています。
必然的に、なぜこれをやりたいのかと聞かれます: 私たちのプロジェクトは既に Google Guice を使用しており (そして GWT で Gin を使用している UI で)、別の IoC コンテナー構成を維持したくない、またはプルインしたくないためです。結果として生じるすべての依存関係。Guice の を使用できる可能性があることはわかってSpringIntegration
いますが、これは最後の手段です。
オブジェクトを手動で接続するためにすべてが利用できるようですが、十分に文書化されていないため、苦労しています。
Spring Data ユーザー ガイドによると、リポジトリ ファクトリをスタンドアロンで使用することが可能です。残念ながら、この例はRepositoryFactorySupport
どちらが抽象クラスであるかを示しています。いくつかの検索の後、私は見つけることができましたJpaRepositoryFactory
JpaRepositoryFactory
トランザクションを自動的に作成しないことを除けば、実際にはかなりうまく機能します。トランザクションは手動で管理する必要があります。そうしないと、データベースに何も永続化されません。
entityManager.getTransaction().begin();
repositoryInstance.save(someJpaObject);
entityManager.getTransaction().commit();
@Transactional
問題は、注釈が自動的に使用されないことであることが判明しました。TransactionInterceptor
ありがたいことに、JpaRepositoryFactory
はコールバックを取得して、返される前に、生成されたリポジトリ プロキシにさらに AOP アドバイスを追加できます。
final JpaTransactionManager xactManager = new JpaTransactionManager(emf);
final JpaRepositoryFactory factory = new JpaRepositoryFactory(emf.createEntityManager());
factory.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory) {
factory.addAdvice(new TransactionInterceptor(xactManager, new AnnotationTransactionAttributeSource()));
}
});
これは物事がうまくいっていないところです。コードでデバッガーをステップ実行すると、TransactionInterceptor
確かにトランザクションが作成されますが、間違っていEntityManager
ます。Spring はEntityManager
、現在実行中のスレッドを見てアクティブを管理します。はTransactionInterceptor
これを行い、スレッドへのアクティブなEntityManager
バインドがないことを確認し、新しいスレッドを作成することを決定します。
ただし、この newは、作成されてコンストラクターにEntityManager
渡されたものと同じインスタンスではなく、. 問題は、どうすれば と を同じように使用できるかということです。JpaRepositoryFactory
EntityManager
TransactionInterceptor
JpaRepositoryFactory
EntityManager
アップデート:
これを書きながら、問題を解決する方法を見つけましたが、それでも理想的な解決策ではないかもしれません. この解決策は別の回答として投稿します。私が解決した方法よりも、Spring Data JPA をスタンドアロンで使用するためのより良い方法についての提案をお待ちしております。