/ / hql fetch sur jointure externe droite - hibernate, hql

hql va chercher sur la jointure externe droite - hibernate, hql

[Scénario]

J'ai deux tables - région et sous-station. Une région peut avoir plusieurs sous-stations, mais une sous-station ne peut appartenir qu'à une seule région. Une région ne peut pas non plus avoir de sous-station. c'est-à-dire une région sans sous-station.

Dans la classe modèle, j'ai deux classes, Région et Sous-station. La sous-station contient un champ de type région, et c'est ainsi que j'ai établi une relation de clé étrangère entre une région et une sous-station.

Je fais une jointure externe droite sur le langage de requête Hibernate comme ceci:

from Substation sub right outer join fetch sub.region

La raison pour laquelle je fais la jointure externe droite est parce que dans la liste qui est retournée après l'exécution de la requête, je veux également afficher les régions qui n'ont pas de sous-station.

[Base de données]

Voici à quoi ressemble ma table de région:

mysql> select * from region;
+----+----------------+-------+
| id | name           | state |
+----+----------------+-------+
|  1 | Entire Network |       |
|  4 | aa             | AK    |
-------Data abbreviated due to space consumption-------

Voici à quoi ressemble ma table de sous-station:

mysql> select * from substation;
+---------+-------------+-----------+-----------+----+
| name    | lon         | lat       | region_id | id |
+---------+-------------+-----------+-----------+----+
| aga     |    3.000000 | 23.000000 |         1 |  1 |
| sjstest |   46.000000 | 22.100000 |         7 |  2 |
----------Data abbreviated due to space consumption--------

Après la jointure externe droite, voici ce que j'obtiens:

mysql> select * from substation right outer join region on region.id=substation.region_id;
+---------+-------------+-----------+-----------+------+----+----------------+-------+
| name    | lon         | lat       | region_id | id   | id | name           | state |
+---------+-------------+-----------+-----------+------+----+----------------+-------+
| aga     |    3.000000 | 23.000000 |         1 |    1 |  1 | Entire Network |       |
| addtest | -104.501953 | 47.813155 |         1 |    8 |  1 | Entire Network |       |
| NULL    |        NULL |      NULL |      NULL | NULL |  4 | aa             | AK    |
----------Data abbreviated due to space consumption-----------------------------------

Comme vous pouvez le voir, dans la dernière ligne, la première partie est nulle car cette région "aa" n'a pas de sous-station.

[Problème]

S'il y a des régions qui n'ont pas de sous-station, je m'attends à ce que hibernate me renvoie un objet Substation avec tous les autres jeux de données à null et le seul jeu de données de région.

Mais ce que j'obtiens, c'est que la mise en veille prolongée me renvoie des objets nuls chaque fois qu'elle trouve des données comme la 3e ligne.

Donc, ma question est la suivante: pourquoi hibernate ne fait-il pas de chargement rapide lorsque je spécifie l'extraction dans la requête. Après avoir effectué un chargement rapide, il doit initialiser un nouvel objet Substation et y définir une région.

Dans tous les cas, cela ne devrait jamais me renvoyer une valeur nulle.

[Exemple]

Juste pour demonstation, c'est ce que j'obtiens quand j'imprime les résultats

com.tollgrade.smartgrid.model.Substation@10cc6578
com.tollgrade.smartgrid.model.Substation@ed192112
null

Notez que le troisième est nul car il avaitdes données comme la 3e ligne que j'ai mentionnée dans la sortie de ma base de données. Il ne doit pas être nul. Il doit contenir un objet substaion dont tous les autres champs sont nuls, à l'exception du champ region.

[DÉBOGUER]

Voici la sortie de débogage HQL:

014-05-15 15:50:31.122 DEBUG [org.hibernate.SQL] - select substation0_.id as id91_0_, region1_.id as id85_1_, substation0_.region_id as region2_91_0_, substation0_.name as name91_0_, substation0_.lon as lon91_0_, substation0_.lat as lat91_0_, region1_.name as name85_1_, region1_.state as state85_1_ from smartgrid.substation substation0_ right outer join smartgrid.region region1_ on substation0_.region_id=region1_.id
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id91_0_]
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id85_1_]
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [8] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [null] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [4] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [2] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [9] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [null] as column [id91_0_]
------------------------------------Abbreviated Output------------------------------------------

Réponses:

0 pour la réponse № 1

La raison pour laquelle hibernate retourne null est parce que dans la requête hibernate:

from Substation sub right outer join fetch sub.region

nous retournons un objet de poste, et quandhibernate ne peut pas trouver de sous-station (le cas d'une région n'ayant pas de sous-station), il n'a pas d'objet sur lequel il pourrait définir les valeurs de région appropriées.

De plus, ne rien donner avant "from" fait que la mise en veille prolongée modifie automatiquement la requête et cela devient essentiellement ceci:

select sub from Substation sub right outer join fetch sub.region

Il ressort clairement de cela que nous sommesen disant spécifiquement hibernate pour me rendre l'objet sous-station. Peu importe que la région soit chargée ou non. Lorsqu'il n'y a pas de sous-station à connecter, l'hibernation ne récupère pas l'objet région région.

Je ne suis pas sûr de ce que j'attendais de la mise en veille prolongée - pour créer automatiquement un objet de sous-station et définir toutes ses valeurs sur null à l'exception de la valeur de région. Pfff !! Jetez un oeil à ce gars. Stupide.

Quoi qu'il en soit, la bonne requête devrait être la suivante:

select sub, reg from Substation sub inner join fetch Region reg sub.region = reg.id

Cette requête renvoie deux objets - Substation et Region. Si la sous-station est nulle, le premier objet sera nul, mais vous aurez toujours le deuxième ensemble d'objets qui est requis.