2012-02-29 2 views
0

Ceci est similaire à question I asked earlier. Les réponses à cette question ont partiellement résolu mon problème, mais j'ai encore quelques difficultés à effectuer le genre de recherche que j'ai spécifié; De plus, j'ai simplement du mal à comprendre comment Hibernate choisit ce qu'il faut retourner dans différents scénarios.Présentation des requêtes HQL sur les objets de collection

Voici mon mapping:

Client { 
    @OneToMany(mappedBy="client",cascade=CascadeType.ALL) 
    private Set<Group> groups = new HashSet<Group>(); 
} 

Group { 
    @ManyToOne (cascade=CascadeType.ALL) 
    private Client client = new Client(); 

    private String name; 
    private String state; //two char state code 
    private String extId; //unique identifier; candidate key, but not the @Id. 
} 

requêtes par nom sont en ligne (par exemple, comme avec des jokers sur les deux extrémités du PARAM); state et extId sont par égalité.

La requête suivante retourne un client unique, seul le groupe de correspondance ci-joint, même si d'autres groupes sont associés au client (à noter à nouveau que extId renvoie uniquement un seul groupe):

select distinct client from Client as client 
inner join client.groups as grp 
where grp.extId = :extId 

cette requête renvoie un seul client, mais avec tous les groupes associés attachés, indépendamment du fait que le code d'état du groupe correspond aux critères:

select distinct client from Client as client 
inner join client.groups as grp 
where grp.state= :state 

Enfin, cette requête renvoie une copie distincte du client pour chaque groupe apparié, et chaque copie contient tous ses groupes associés, indépendamment du fait que le nom du groupe correspond aux critères:

select distinct client from Client as client 
inner join client.groups as grp 
where grp.name like :name 

Je suis nouveau à Hibernate, et je trouve extrêmement frustrant de ne pas pouvoir prédire ce qui va être renvoyé à partir d'une requête donnée. Les trois requêtes sont presque identiques, à l'exception de quelques petites modifications dans la clause WHERE, mais je reçois des résultats radicalement différents pour chacun. J'avais passé du temps à consulter la documentation, mais il me manque partout où ce comportement est expliqué. Quelqu'un peut-il aider à faire la lumière sur ce sujet?

Enfin, ce que je dois vraiment faire est de retourner Client s lors de l'interrogation par Group, et que le client ne contiennent les Group s qui correspondent aux critères de recherche. Existe-t-il un moyen unique de construire une requête HQL, ou devrais-je faire plusieurs requêtes et construire mes objets dans le code?

Merci.

+1

Ce n'est absolument pas ce que j'observe. Êtes-vous sûr que la collection de groupes est paresseuse? Êtes-vous sûr que chaque requête a une clause distincte et n'a pas de clause fetch? Ces trois requêtes, avec la collection alazy-loaded, ont exactement le même comportement dans mes tests, comme prévu. –

+0

Eh bien, ce n'est pas annoté pour le chargement hâtif, et je ne fais pas de fetch join, donc je ne sais pas pourquoi ou comment il serait chargé avec impatience. Il est * utilisé * pour être, donc je vais essayer de nettoyer la construction dans Eclipse. Si c'est le cas, je vais crier et faire des bombes incendiaires, pas nécessairement dans cet ordre. FWIW, quel comportement voyez-vous? Vous avez dit qu'ils sont tous pareils pour vous, mais qu'est-ce que c'est? – Ickster

+0

Chaque requête charge des entités distinctes et tous les éléments de la collection sont présents lors du chargement. –

Répondre

1

La réponse à cette question est double. Premièrement, il y avait un problème avec le harnais de test, qui utilisait (raisonnablement) l'annulation de transaction pour créer des instances de test sans laisser d'artefacts dans la base de données. C'était la source de mes réponses bizarres dans les requêtes.

J'ai réussi à retourner uniquement les valeurs que je voulais dans les collections en changeant simplement en une jointure fetch externe.

Questions connexes