我什么时候应该调用javax.jdo.Query.close(Object)?

时间:2010-10-26 17:44:45

标签: jdo

我试图了解何时应该调用Query.close(Object)或Query.closeAll();

the docs我看到它将“关闭查询结果”并“释放与之关联的所有资源”,但“关闭”是什么意思?这是否意味着我在调用它们之后不能使用我从查询中获取的对象?

我问,因为我试图用像getUser(id)这样的函数划分我的代码,这将创建一个Query,获取User,并销毁查询。如果我必须保持查询只是为了访问用户,那么我不能真正做那种划分。

如果我不在某个物体上打电话会怎么样?它会被收集为垃圾吗?我以后能够访问该对象吗?

如果我能以某种方式进一步说明我的问题,请告诉我。

2 个答案:

答案 0 :(得分:2)

您不能使用查询结果,因为您关闭了它们(即您从query.execute返回的List对象)。您可以访问结果中的对象 ...如果您将它们复制到您自己的列表中,或者在代码中对它们进行了引用。无法调用关闭可能会泄漏内存

答案 1 :(得分:1)

当您的查询方法返回单个对象时,很容易在返回单个对象之前简单地关闭查询。

另一方面,当您的查询方法返回一个集合时,查询方法本身无法在返回结果之前关闭查询,因为查询需要在调用者迭代结果时保持打开状态。

这就要求关闭一个在调用者上返回一个集合的查询,并且如果调用者忽略了关闭查询,则会引入泄漏 - 我认为必须有一种更安全的方式并且存在!

Guido,一位长期以来的DataNucleus用户,创建了一个“自动关闭”集合外观,它包装了JDO的Query.execute方法返回的集合。用法非常简单:将查询结果包装在自动结束集合对象的实例中:

而不是像这样返回Query结果集:

return q.execute();

只需返回一个'自动关闭'包装版本:

return new JDOQueryResultCollection(q, q.execute());

对于调用者来说,它看起来像任何其他Collection,但是包装器保留对创建集合结果的查询的引用,并在GC处理包装器时自动关闭它。

Guido慷慨地允许我们在我们的开源exPOJO库中包含他聪明的自动关闭代码。自动关闭类完全独立于exPOJO,可以单独使用。感兴趣的类在expojo_jdo * .jar文件中,可以从以下位置下载:

http://www.expojo.com/

JDOQueryResultCollection是唯一直接使用的类,但它确实有一些支持类。

只需将jar添加到项目中,然后将com.sas.framework.expojo.jdo.JDOQueryResultCollection导入任何包含将结果作为集合返回的查询方法的Java文件中。

或者,您可以从jar中提取源文件并将其包含在项目中:它们是:

JDOQueryResultCollection.java
Disposable.java
AutoCloseQueryIterator.java
ReadonlyIterator.java
相关问题