如何使用 JDO 持久化管理器?

Posted

技术标签:

【中文标题】如何使用 JDO 持久化管理器?【英文标题】:How to use JDO persistence manager? 【发布时间】:2011-05-10 06:44:16 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

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

对于简单的用例,您可以在需要时创建一个PersistenceManager,然后在finally 子句中关闭它(参见the persistence manager documentation)。

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

您可以在 Servlet 过滤器中调用 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();
        
  

【讨论】:

一个问题:进行搜索/替换并将所有出现的“persistAnce”更改为“persistEnce”,你会更开心。 :-) 我发现这种方法在谷歌应用引擎上不起作用——无论出于何种原因,它在 localhost 上都能完美运行,但 pmf 在生产中意外关闭 @bsautner 如果您发布有关您的问题的问题并在此处提供链接,我很乐意查看。不过我已经有一段时间没有使用 GAE 了。

以上是关于如何使用 JDO 持久化管理器?的主要内容,如果未能解决你的问题,请参考以下文章

关闭持久性管理器后如何使查询结果可用

在哪里使用 JDO/Google App Engine 设置 TransactionOptions?

通过 GWT-RPC 发送持久的 JDO 实例

Datanucleus/JDO,持久化和检索 java.util.Set 属性

JDO - 更新对象

JPA 和 JDO 规范有啥区别?