如何解决对象管理器已关闭错误?

时间:2011-04-18 12:02:17

标签: google-app-engine jdo

如果有人能指点我关于如何关闭的教程或最佳实践,我将不胜感激 JDO连接。 每当我包含finally块时,我总是会出现javax.jdo.JDOUserException: Object Manager has been closed错误 我的代码如下:

public static List<AgentEntity> findAgentEntityByString(String id) {
    List<AgentEntity> agententity = new ArrayList<AgentEntity>();
    if (id == null) {
      return null;
    }
    try {
        Query q = pm.newQuery("select id from " + AgentEntity.class.getName());
        agententity = (List<AgentEntity>) q.execute();
    } catch(Exception ex) {
        log.warning(ex.getMessage());
    }
        return agententity;
  }

此致

4 个答案:

答案 0 :(得分:3)

避免此延迟加载问题的一种可能解决方案是使用size()方法强制PersistenceManager对象在关闭之前从数据存储区加载结果列表。

public static List<AgentEntity> findAgentEntityByString(String id) {
    List<AgentEntity> agententity = new ArrayList<AgentEntity>();
    if (id == null) {
      return null;
    }
    try {
        Query q = pm.newQuery("select id from " + AgentEntity.class.getName());
        agententity = (List<AgentEntity>) q.execute();
        agententity.size()  //Should populate the returned list
        return agententity;
    } finally {
      pm.close();
    }        
  }

参考here

答案 1 :(得分:0)

为什么要在这里关闭PersistenceManager? 如果要关闭查询,则应使用其中一个 javax.jdo.Query.closeAll()javax.jdo.Query.close(Object result)。 因此,您可以执行结果的临时副本,而不是关闭查询及其结果:

public static List<AgentEntity> findAgentEntityByString(String id) {
  if (id == null) {
    return null;
  }
  Query q = null;
  try {
      q = pm.newQuery("select id from " + AgentEntity.class.getName());
      return new ArrayList<AgentEntity>((List<AgentEntity>) q.execute());
  } finally {
    if(q!= null){
        q.closeAll();
    }
  }        
} 

或者您可以稍后明确关闭结果:

public static List<AgentEntity> findAgentEntityByString(String id) {
  if (id == null) {
    return null;
  }
  Query q = pm.newQuery("select id from " + AgentEntity.class.getName());
  return (List<AgentEntity>) q.execute();
  }        
}
....
List agents = X.findAgentEntityByString("Foobar");
....
pm.close(agents);

答案 2 :(得分:0)

尝试在获取PM后立即设置获取计划,然后在执行查询之前将其设置为all:

导入javax.jdo.FetchPlan;

    pm = PMF.get().getPersistenceManager();
    FetchPlan fp = pm.getFetchPlan();
    fp.setGroup(FetchPlan.ALL);

答案 3 :(得分:0)

实际上,在这里回答了为我解决的问题:

Why do I get "Persistence Manager has been closed" exception

我有一个对持久性管理器的实例引用,我刚刚创建了一个本地实例并修复了所有错误