5

关于如何创建/使用 JDO 持久性管理器(PM,以下简称),我有两个问题。

比如说,在一个 Java Web 应用程序中,如果我有 10 个实体,它们在逻辑上可以分为 2 个组(例如,5 个用户相关实体和 5 个业务相关实体)

  1. 我应该需要两个不同的 PM 来管理这 2 个组还是只有一个 PM 就足够了?
  2. 关于初始化,我应该使用 PM 的单例实例(将在给定时间点由所有使用该应用程序的用户共享)还是应该为每个会话创建一个 PM?
4

1 回答 1

14

根据JDO 文档,您为每个数据存储创建一个PersistenceManagerFactory。如果您使用 JDO 通过 SQL 访问数据库并且您有多个数据库,那么PersistenceManagerFactory每个数据库都需要一个(因为您需要在创建 JDBC URL、用户名和密码时指定 JDBC URL、用户名和密码PersistenceManagerFactory)。

对于简单的用例,您可以在需要时创建一个并在一个子句PersistenceManager中关闭它(请参阅持久性管理器文档)。finally

如果您使用事务,并且更新实体的代码可以分布在多个方法或对象中,我建议PersistenceManager按需创建并将其存储在一个ThreadLocal(或者如果您使用 Guice 或 Spring,则存储在请求范围的对象中)。这将确保执行更新的任何代码都参与当前事务。确保PersistenceManager在请求结束时关闭。

如果你只需要一个持久化管理器工厂,你可以这样做:

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为单例。

您可以调用finishRequestServlet 过滤器:

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 回答