C'est en fait le comportement attendu si j'ai bien compris votre configuration.
Hibernate ne renvoie pas de résultats distincts pour une requête avec la récupération de jointure externe activée pour une collection (même si j'utilise le mot-clé distinct)? Tout d'abord, vous devez comprendre SQL et comment les OUTER JOIN fonctionnent dans SQL. Si vous ne comprenez pas et ne comprenez pas complètement les jointures externes dans SQL, ne continuez pas à lire cet article de FAQ mais consultez un manuel ou un didacticiel SQL. Sinon, vous ne comprendrez pas l'explication suivante et vous vous plaindrez de ce comportement sur le forum Hibernate.
Exemples typiques qui peuvent renvoyer des références dupliquées du même objet Order:
List result = session.createCriteria(Order.class)
.setFetchMode("lineItems", FetchMode.JOIN)
.list();
<class name="Order">
...
<set name="lineItems" fetch="join">
List result = session.createCriteria(Order.class)
.list();
List result = session.createQuery("select o from Order o left join fetch o.lineItems").list();
Tous ces exemples produisent la même instruction SQL:
SELECT o.*, l.* from ORDER o LEFT OUTER JOIN LINE_ITEMS l ON o.ID = l.ORDER_ID
Vous voulez savoir pourquoi les doublons sont là? Regardez le jeu de résultats SQL, Hibernate ne cache pas ces doublons sur le côté gauche du résultat joint externe mais renvoie tous les doublons de la table de pilotage. Si vous avez 5 commandes dans la base de données et que chaque commande comporte 3 éléments de campagne, l'ensemble de résultats comportera 15 lignes. La liste des résultats Java de ces requêtes comportera 15 éléments, tous de type Order. Seules 5 instances Order seront créées par Hibernate, mais les doublons du jeu de résultats SQL sont conservés en tant que références dupliquées à ces 5 instances. Si vous ne comprenez pas cette dernière phrase, vous devez lire sur Java et la différence entre une instance sur le tas Java et une référence à une telle instance.
(Pourquoi une jointure externe à gauche? Si vous avez une campagne supplémentaire sans élément de campagne, l'ensemble de résultats serait de 16 lignes avec NULL remplissant le côté droit, où les données d'élément de campagne sont pour une autre campagne. Vous voulez des campagnes même si ils n'ont pas d'éléments de campagne, n'est-ce pas? Sinon, utilisez une extraction par jointure interne dans votre HQL).
Hibernate ne filtre pas ces références dupliquées par défaut. Certaines personnes (pas vous) le souhaitent. Comment pouvez-vous les filtrer?
Comme ça:
Collection result = new LinkedHashSet( session.create*(...).list() );