我什么时候应该调用 javax.jdo.Query.close(Object)?
我试图了解何时应该调用 Query.close(Object) 或 Query.closeAll();
来自文档 我看到它将“关闭查询结果”并“释放与其关联的所有资源”,但“关闭”是什么意思?这是否意味着我不能使用在调用 close 后从查询中获得的对象?
我问这个问题是因为我试图将我的代码与 getUser(id) 等函数分开,它将创建一个查询、获取用户并销毁查询。如果我必须保留查询只是为了访问用户,那么我实际上无法进行这种划分。
如果我不对对象调用 close 会发生什么?会被当作垃圾收集吗?我稍后可以访问该对象吗?
如果我可以以某种方式进一步说明我的问题,请告诉我。
I'm trying to understand when I should call Query.close(Object) or Query.closeAll();
From the docs I see that it will "close a query result" and "release all resources associated with it," but what does "close" mean? Does it mean I can't use objects that I get out of a Query after I've called close on them?
I ask because I'm trying to compartmentalize my code with functions like getUser(id), which will create a Query, fetch the User, and destroy the query. If I have to keep the Query around just to access the User, then I can't really do that compartmentalization.
What happens if I don't call close on an object? Will it get collected as garbage? Will I be able to access that object later?
Please let me know if I can further specify my question somehow.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法使用查询结果,因为您关闭了它们(即从 query.execute 返回的 List 对象)。您可以访问结果中的对象...如果您将它们复制到您自己的列表中,或者在代码中引用了它们。未能调用 close 可能会泄漏内存
You can't use the query results since you closed them (i.e the List object you got back from query.execute). You can access the objects in the results ... if you copied them to your own List, or made references to them in your code. Failure to call close can leak memory
当您的查询方法返回单个对象时,很容易在返回单个对象之前关闭查询。
另一方面,当您的查询方法返回集合时,查询方法本身无法在返回结果之前关闭查询,因为在调用者迭代结果时查询需要保持打开状态。
这将关闭返回集合的查询的责任放在调用者身上,如果调用者忽略关闭查询,则可能会导致泄漏 - 我认为必须有一种更安全的方法,而且确实有!
Guido 是 DataNucleus 的长期用户,他创建了一个“自动关闭”集合外观,它包装了 JDO 的 Query.execute 方法返回的集合。用法非常简单:将查询结果包装在自动关闭集合对象的实例中:
而不是像这样返回查询结果集:
只需返回它的“自动关闭”包装版本:
对于调用者来说,它看起来像任何其他集合但包装器保留对创建收集结果的查询的引用,并在 GC 处置包装器时自动关闭它。
Guido 善意地允许我们将他巧妙的自动关闭代码包含在我们的开源 exPOJO 库中。自动关闭类完全独立于 exPOJO,可以单独使用。感兴趣的类位于 expojo_jdo*.jar 文件中,可以从以下位置下载:
http://www.expojo.com/
JDOQueryResultCollection 是唯一直接使用的类,但它确实有一些支持类。
只需将 jar 添加到您的项目中,并将 com.sas.framework.expojo.jdo.JDOQueryResultCollection 导入到任何包含以集合形式返回结果的查询方法的 Java 文件中。
或者,您可以从 jar 中提取源文件并将它们包含在您的项目中:它们是:
When your query method returns a single object it is easy to simply close the query before returning the single object.
On the other hand, when your query method returns a collection the query method itself can not close the query before returning the result because the query needs to stay open while the caller is iterating through the results.
This puts the responsibility for closing a query that returns a collection on the caller and can introduce leaks if the caller neglects to close the query - I thought there must be a safer way and there is!
Guido, a long time DataNucleus user, created a 'auto closing' collection facade that wraps the collection returned by JDO's Query.execute method. Usage is extremely simple: Wrap the query result inside an instance of the auto closing collection object:
Instead of returning the Query result set like this:
simply return an 'auto closing' wrapped version of it:
To the caller it appears like any other Collection but the wrapper keeps a reference to the query that created the collection result and auto closes it when the wrapper is disposed of by the GC.
Guido kindly gave us permission to include his clever auto closing code in our open source exPOJO library. The auto closing classes are completely independent of exPOJO and can be used in isolation. The classes of interest are in the expojo_jdo*.jar file that can be downloaded from:
http://www.expojo.com/
JDOQueryResultCollection is the only class used directly but it does have a few supporting classes.
Simply add the jar to your project and import com.sas.framework.expojo.jdo.JDOQueryResultCollection into any Java file that includes query methods that return results as a collection.
Alternatively you can extract the source files from the jar and include them in your project: They are: