Sur mon projet, j'utilise Groovy avec les données Specification
de Spring Data JPA pour construire des requêtes Hibernate.Avec les critères JPA, comment extraire une entité enfant d'une entité jointe sans extraire l'entité jointe?
Je ne peux pas fournir mes requêtes réelles, mais pour illustrer mon problème, disons que j'ai des entités de construction, et que chaque bâtiment a des étages et que chaque étage a des pièces et des fenêtres.
Le comportement que je tente de simuler est quelque chose comme cette requête SQL natif:
SELECT b.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
LEFT OUTER JOIN room r ON f.id = r.floor_id
WHERE w.id = 1;
J'ai une spécification similaire à ce qui suit:
public class MySpec implements Specification<Building> {
@Override
public Predicate toPredicate(final Root<Building> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
final Join floorsJoin = root.join("floors");
final Join windowsJoin = floorsJoin.join("windows");
//I'd like to remove this line
final Fetch floorsFetch = root.fetch("floors"); // <---
floorsFetch.fetch("rooms", JoinType.LEFT);
cb.equal(windowsJoin.get("id"), 1L);
}
}
La ligne annotée ci-dessus est mon problème . Si je laisse, la requête générée ressemble à quelque chose comme ceci:
SELECT b.*, f2.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
INNER JOIN floor f2 ON b.id = f2.building_id
LEFT OUTER JOIN room r ON f2.id = r.floor_id
WHERE w.id = 1;
(notez le double INNER JOIN
de floor
et les données f2.*
non nécessaires)
Si je le supprimer, et utiliser le floorsJoin
au lieu de chercher des chambres , je reçois l'erreur Hibernate suivante:
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
les f2.*
inutiles données seraient OK sauf que je ne peux pas remplacer le floorsJoin
ci-dessus avec t il floorsFetch
parce que j'ai besoin de rejoindre la table windows
(sans aller chercher windows
) et la classe Fetch
n'a pas de méthode .join
.
J'ai du mal à comprendre comment j'accomplirais ce dont j'ai besoin tout en générant une seule requête; Je dois sûrement manquer quelque chose de simple. Toutes les pensées ou les conseils que vous pourriez fournir seraient grandement appréciés.
Merci beaucoup, B.J.