5

JDO 永続マネージャ (以下、PM) の作成/使用方法について 2 つの質問があります。

Java Web アプリケーションで、10 個のエンティティがあり、論理的に 2 つのグループにグループ化できるとします (たとえば、5 つのユーザー関連エンティティと 5 つのビジネス関連エンティティ)。

  1. これら 2 つのグループを管理するには 2 つの異なる PM が必要ですか、それとも 1 つの PM だけで十分ですか?
  2. 初期化に関して、PM のシングルトン インスタンス (特定の時点でアプリを使用しているすべてのユーザーによって共有される) を使用するか、セッションごとに PM を作成する必要がありますか?
4

1 に答える 1

14

JDO ドキュメントによると、PersistenceManagerFactoryデータストアごとに 1 つ作成します。SQL 経由でデータベースにアクセスするために JDO を使用していて、複数のデータベースがある場合は、PersistenceManagerFactoryデータベースごとに 1 つ必要になります ( を作成するときに JDBC URL、ユーザー名、およびパスワードを指定する必要があるためPersistenceManagerFactory)。

単純な使用例では、PersistenceManager必要なときに を作成し、それをfinally句で閉じることができます (持続性マネージャーのドキュメントを参照してください)。

トランザクションを使用し、エンティティを更新するためのコードが複数のメソッドまたはオブジェクトに分散している可能性がある場合は、PersistenceManagerオンデマンドを作成してThreadLocal(Guice または Spring を使用している場合はリクエスト スコープのオブジェクト) に保存することをお勧めします。これにより、更新を行うすべてのコードが現在のトランザクションに参加するようになります。PersistenceManagerリクエストの最後でを必ず閉じてください。

永続化マネージャー ファクトリが 1 つだけ必要な場合は、次のようにします。

public class Datastore {
  private static PersistenceManagerFactory PMF;
  private static final ThreadLocal<PersistenceManager> PER_THREAD_PM
      = new ThreadLocal<PersistenceManager>();

  public static void initialize() {
     if (PMF != null) {
       throw new IllegalStateException("initialize() already called");
     }
     PMF = JDOHelper.getPersistenceManagerFactory("jdo.properties");
  }

  public static PersistenceManager getPersistenceManager() {
    PersistenceManager pm = PER_THREAD_PM.get();
    if (pm == null) {
      pm = PMF.getPersistenceManager();
      PER_THREAD_PM.set(pm);
    }
    return pm;
  }

  public static void finishRequest() {
    PersistenceManager pm = PER_THREAD_PM.get();
    if (pm != null) {
      PER_THREAD_PM.remove();
      Transaction tx = pm.currentTransaction();
      if (tx.isActive()) {
         tx.rollback();
      }
      pm.close();
    }
  }
}

永続化マネージャーを必要とするコードはすべて呼び出すことができますDatastore.getPersistenceManager()

注:質問に答える目的で、すべての静的メソッドを使用して簡単にしました。Guice のような依存性注入フレームワークを使用していた場合、メソッドを非静的にDatastoreし、Singleton としてバインドします。

finishRequestサーブレット フィルターを呼び出すことができます。

public class PersistenceManagerFilter implements javax.servlet.Filter {

  public init(FilterConfig filterConfig) {
    Datastore.initialize();
  }

  public void doFilter(ServletRequest request, 
      ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    try {
      chain.doFilter(request, response);
    } finally {
      Datastore.finishRequest();
    }    
  }
}
于 2010-11-15T15:48:25.193 に答える