2017-09-08 2 views
0

Eh bien bonjour,Mise en veille prolongée paresseux chercher vide après un résultat était vide

Je vous écris une application console qui est connecté à une base de données Postgres et je suis tombé sur le problème suivant:

public List<String> getCommonInterestsOfMyFriends(long personId) { 

    Person personOfIntrest = session.get(Person.class, personId); 
    //fetch friends from db via get Call 
    int size = personOfIntrest.getFriends().size(); 
    int size2 = personOfIntrest.getFriendsWith().size(); 
    int size3 = personOfIntrest.getIntrests().size(); 

    Set<Tag> interests = personOfIntrest.getIntrests(); 

    Set<Person> allFriends = personOfIntrest.getFriendships().keySet(); 

    for (Person p : allFriends) { 

     Set<Tag> friendsInterests = p.getIntrests(); 
     friendsInterests.retainAll(interests); 
    } 
} 

A La personne peut avoir des intérêts modélisés par une relation ManyToMany avec une table de jointure. J'appelle le code ci-dessus plusieurs fois et ça marche totalement bien jusqu'à ce que je tombe sur une personne qui n'a aucun intérêt. Après cela, pour chaque personne, l'ensemble «intérêts» est vide, même si l'ensemble a été chargé avec succès auparavant.

Pour initialiser l'association paresseuse j'appelle les getters, j'ai aussi essayé aille chercher rejoint

// fetch associated data via fetch join 
    Query q = session.createQuery("SELECT p FROM Person p " 
           + "LEFT JOIN FETCH p.friends " 
           + "LEFT JOIN FETCH p.friendsWith " 
           + "LEFT JOIN FETCH p.intrests " 
           + "WHERE p.id = :id"); 
    q.setParameter("id", personId); 
    Person personOfIntrest = (Person) q.getSingleResult(); 

toujours le même problème. L'ensemble des intérêts est chargé avec succès tant que je n'ai pas interrogé une personne qui n'a aucun intérêt, après que l'ensemble est vide pour toute personne. Tout est dans la même session.

Merci pour l'aide, Sincères salutations

+0

Il est difficile de comprendre ce qui se passe sans savoir lequel des nombreuses personnes invoved dans ce code que vous parlez, quelles personnes sont liés à quels autres, et qui vous appelle à faire.Mais le code appelle retainAll() sur les intérêts de nombreuses personnes, ce qui supprime les intérêts de l'ensemble.Je ne suis pas surpris que vous vous retrouvez avec des ensembles vides après un alors, en particulier si l'une des personnes n'a aucun intérêt –

+0

Oui, le problème est le premier appel de getIntrests() à la ligne 9. Laissez-moi peut-être vous donner un exemple: ery pour Person avec ID 9, cette personne a une colonne relative dans la table de jointure, set intrests est chargé, tout va bien. Ensuite, je demande pour la personne avec l'ID 10 qui n'a pas d'intrests, de sorte que l'ensemble est vide, aussi bien. Maintenant dans la même session, si je demande à nouveau à la personne 9, l'ensemble des intrests est maintenant vide, même pour toutes les personnes suivantes, qu'elles aient ou non des intestins. Tout cela est avant la partie de l'intersection, je vois pourquoi cela pourrait être source de confusion, je devrais peut-être supprimer cette partie – IVIerlski

+0

La partie que vous avez supprimé est probablement la cause de votre problème. La méthode est censée rendre des intérêts communs à plusieurs personnes, mais elle modifie les intérêts de tous les amis de la personne trouvée. Pourquoi modifiez-vous ces ensembles? Ne croyez pas que c'est un bug dans Hibernate. c'est un bug dans ton code. –

Répondre

0

Pour ceux qui se demandent à l'avenir:

J'ai fini de manipuler les intérêts des amis en appelant friendsInterests.retainAll(interests); sur le plateau. Comme ce changement n'était pas persistant, je ne pensais pas que c'était une grosse affaire. J'ai fait l'erreur de penser qu'appeler les objets persistants getter ou la requête à nouveau rechargerait l'objet de la base de données, même dans la même session. Ce n'est pas le cas!

I profondément copié l'ensemble avant l'appel et savent tout fonctionne comme prévu:

for (Person p : allFriends) { 

     Set<Tag> friendsInterests = p.getIntrests(); 
     Set<Tag> fiCopy = new HashSet<Tag>(); 
     fiCopy.addAll(friendsInterests); 

     fiCopy.retainAll(interests); 
}