You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDO中何时调用Query.close与关闭Persistence Manager?结果关闭错误求解

问题解决方案

问题原因

JDO的查询结果集是延迟加载的,返回的List只是一个代理对象,实际数据并未立刻从Datastore加载到内存;同时查询返回的User对象是附着在PersistenceManager(PM)上的持久化实例,一旦PM关闭,这些实例就无法访问。你尝试用new ArrayList<>(user)复制时,部分JDO实现可能不会立刻遍历整个集合触发加载,或者复制后的List依然依赖PM的连接,导致后续访问时PM已关闭,抛出“Query result has been closed”错误。

解决方法

核心思路是在关闭PM和Query前,将数据完全加载为脱离PM依赖的普通对象,以下两种方式均可:

1. 使用JDO对象分离API

通过pm.detachCopyAll()将查询结果转换为脱离PM的普通对象,返回的List完全独立,不受后续PM关闭的影响:

public List<User> findAll() {
    LOGGER.info("Getting users list");
    Query query = null;
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
        query = pm.newQuery(User.class);
        List<User> result = (List<User>) query.execute();
        // 分离所有对象,解除对PM的依赖
        List<User> detachedUsers = pm.detachCopyAll(result);
        return new ArrayList<>(detachedUsers);
    } catch (Exception e) {
        LOGGER.error("Error while getting user list", e);
        return Collections.emptyList();
    } finally {
        if(query != null) query.closeAll();
        pm.close();
    }
}

2. 手动遍历触发完全加载

在PM关闭前手动遍历整个结果集,将每个对象复制到新List中,确保所有数据都加载到内存:

public List<User> findAll() {
    LOGGER.info("Getting users list");
    Query query = null;
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
        query = pm.newQuery(User.class);
        List<User> userList = new ArrayList<>();
        // 遍历结果集,触发所有数据加载到内存
        for (User user : (List<User>) query.execute()) {
            userList.add(user);
        }
        return userList;
    } catch (Exception e) {
        LOGGER.error("Error while getting user list", e);
        return Collections.emptyList();
    } finally {
        if(query != null) query.closeAll();
        pm.close();
    }
}

关于关闭资源的说明

是的,必须关闭Query和Persistence Manager:

  • PersistenceManager对应Datastore的连接资源,不关闭会导致连接泄漏,耗尽数据库连接池;
  • Query的closeAll()会释放查询相关的游标、临时缓存等资源,避免资源浪费。
    关键要确保在关闭资源之前,已完成数据的加载和分离,让返回的List不再依赖这些资源。

内容的提问来源于stack exchange,提问作者Kiran Subedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:47:46