Java SE 7 を使用してデスクトップ アプリケーションに取り組んでいます。アプリケーションは複数のスレッドを使用し、作成された各スレッドに DAO クラスを挿入してデータベースにアクセスします。永続層として、EclipseLink と JPA を使用しています。EntityManager は、コンストラクター注入を使用して DAO クラスに注入されます。これはスレッド セーフではないため、次のようにプロバイダーを使用するアプローチを採用しました。
public PluginInstanceJpaController implements IPluginInstanceDao {
private EntityManager em;
@Injected
public PluginInstanceJpaController(Provider<EntityManager> emp) {
this.em = emp.get();
}
@Transactional
public void create(PluginInstance foo) throws Exception {
em.persist(foo);
}
}
ただし、まったく同じ EntityManager インスタンスが各 DAO に注入されます。それをセットアップするために、私は Guice によって提供される JpaPersistModule を使用しました。これまでのところ、私のセットアップにはシングルトンがないと確信しています。
注入時に EntityManager の新しいインスタンスを作成するように Guice に指示する方法を知っている人はいますか?
別のアプローチでは、EntityManagerFactory と EntityManager のカスタム プロバイダーを試し、JpaPersistModule を私のビジネスから除外しました。これにより、DAO ごとに EntityManager インスタンスが生成されましたが、@Transactional アノテーション付きメソッドは傍受されませんでした。
この問題の解決策をいただければ幸いです。これまでありがとう!
- - 編集 - -
DAO クラスは、それらを使用している Runnable に注入されます。Runnable はプロバイダーを通じても提供されます。私のモジュール構成は次のようになります。
public class RepositoryModule extends AbstractModule {
@Override
protected void configure() {
// DAO bindings
bind(IObjectStoreDao.class).to(ObjectStoreJpaController.class);
bind(IPluginInstanceDao.class).to(PluginInstanceJpaController.class);
}
@Provides
public PluginMonitor newMonitor(IPluginInstanceDao plugDao, IObjectStoreDao osDao) {
PluginMonitor m = new PluginMonitor();
m.setPluginInstanceDao(plugDao);
m.setObjectStoreDao(osDao);
return m;
}
}
ここで PluginMonitor は私の Runnable です。インジェクター自体はメインスレッドで作成されます...これが問題だったのでしょうか?