2010-10-26 47 views
0

J'essaie de comprendre quand je devrais appeler Query.close (Object) ou Query.closeAll();Quand devrais-je appeler javax.jdo.Query.close (Object)?

De the docs Je vois qu'il va "fermer un résultat de requête" et "libérer toutes les ressources qui lui sont associées", mais que signifie "fermer"? Cela signifie-t-il que je ne peux pas utiliser les objets que je sors d'une requête après les avoir appelés?

Je demande parce que j'essaie de compartimenter mon code avec des fonctions comme getUser (id), qui va créer une requête, aller chercher l'utilisateur et détruire la requête. Si je dois garder la requête juste pour accéder à l'utilisateur, alors je ne peux pas vraiment faire cette compartimentation. Que se passe-t-il si je n'appelle pas sur un objet? Sera-t-il collecté comme déchet? Serai-je capable d'accéder à cet objet plus tard?

S'il vous plaît laissez-moi savoir si je peux préciser plus en détail ma question d'une manière ou d'une autre.

Répondre

2

Vous ne pouvez pas utiliser les résultats de la requête depuis leur fermeture (c'est-à-dire l'objet Liste que vous avez récupéré à partir de query.execute). Vous pouvez accéder à les objets dans les résultats ... si vous les avez copiés dans votre propre liste, ou y avez fait référence dans votre code. L'absence d'appel peut entraîner une fuite de mémoire

1

Lorsque votre méthode de requête renvoie un seul objet, il est facile de simplement fermer la requête avant de renvoyer l'objet unique. En revanche, lorsque votre méthode de requête renvoie une collection, la méthode de requête elle-même ne peut pas fermer la requête avant de renvoyer le résultat car la requête doit rester ouverte pendant que l'appelant parcourt les résultats. Cela met la responsabilité de fermer une requête qui renvoie une collection sur l'appelant et peut introduire des fuites si l'appelant néglige de fermer la requête - je pensais qu'il devait y avoir un moyen plus sûr et il y en a! Guido, un utilisateur DataNucleus de longue date, a créé une façade de collection 'fermeture automatique' qui enveloppe la collection renvoyée par la méthode Query.execute de JDO. L'utilisation est extrêmement simple: Enroulez le résultat d'une requête dans une instance de l'objet de collection de fermeture automatique:

au lieu de retourner le résultat de requête établi comme ceci:

return q.execute(); 

retourner simplement une version enveloppée « de fermeture automatique » de il:

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

pour l'appelant, il apparaît comme toute autre collection, mais l'emballage conserve une référence à la requête qui a créé le résultat de la collecte et ferme automatiquement lorsque l'emballage est éliminé par le GC. Guido nous a gentiment donné la permission d'inclure son code intelligent de fermeture automatique dans notre librairie open source exPOJO. Les classes de fermeture automatique sont complètement indépendantes de exPOJO et peuvent être utilisées isolément. Les classes d'intérêt sont dans le expojo_jdo * fichier .jar qui peut être téléchargé à partir de:

http://www.expojo.com/

JDOQueryResultCollection est la seule classe utilisée directement, mais elle a quelques classes de support.

Ajoutez simplement le fichier jar à votre projet et importez com.sas.framework.expojo.jdo.JDOQueryResultCollection dans n'importe quel fichier Java incluant des méthodes de requête qui renvoient les résultats en tant que collection.

Sinon, vous pouvez extraire les fichiers source du pot et de les inclure dans votre projet: Ils sont:

JDOQueryResultCollection.java 
Disposable.java 
AutoCloseQueryIterator.java 
ReadonlyIterator.java