-
Signification de
select d from TKBData d JOIN d.columns c WHERE c.name = column1
est- Rechercher un objet TKBData auquel il a une
column
associée objet pour lequelname
estcolumn1
- Une fois qu'il a été décidé quel TKBData a au moins une
column
objet pour lequelname
estcolumn1
, puis il renverra toute sacolumn
associée objets sur lesquels vous n'avez aucun contrôle dans JPA. (voir Ma réponse à une autre question ). L'alternative consiste à écrire du sql natif et à renvoyer des objets non-entité personnalisés - Par exemple, vous avez
TKBDATA_1
aveccolumn1
etcolumn2
associé, vous avez égalementTKBDATA_2
aveccolumn3
associé. - Lorsque vous exécuterez votre requête, elle ignorera
TKBDATA_2
et décide de retournerTKBDATA_1
car il a au moins unecolumn
objet avecname
=column2
. Mais après cela vous ne contrôlez pas lacolumn
associée objets à renvoyer pourTKBDATA_1
et JPA renverra tous les objets de colonne associés - Si vous n'êtes pas sûr de la raison, lisez la session d'hibernation. Comment elle fournit une présentation unique de toute entrée associée en mémoire. C'est la base de sa
dirty checking
etrepeatable read
- Rechercher un objet TKBData auquel il a une
-
Mettez à jour votre
@OneToMany
comme suit
@OneToMany(fetch = FetchType.EAGER,
cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
@JoinTable(name = "TKBDATA_TKBCOLUMN",
joinColumns = @JoinColumn(name = "TKBDATA_ID"),
inverseJoinColumns = @JoinColumn(name = "COLUMNS_ID"))
private Set<TKBColumn> columns = Sets.newHashSet();
-
En ce qui concerne le langage de requête JPA, j'aimerais penser en termes d'interrogation d'une collection d'objets en mémoire.
-
Essayez maintenant de décrire la signification des deux requêtes suivantes en termes d'objets.
select d from TKBData d LEFT JOIN d.columns c WHERE c.name = :name
vs
select d from TKBData d JOIN d.columns c WHERE c.name = :name
-
N'oubliez pas, contrairement à SQL où vous sélectionnez toutes les colonnes ici, vous avez dit que vous souhaitez sélectionner des objets TKBData et restreindre les objets TKBData à renvoyer.
-
Donc, pour obtenir le même résultat qu'avec votre sql natif, utilisez la deuxième requête JPA
Remarque :
Même si vous avez utilisé une jointure gauche dans votre requête sql, il s'agit en fait d'une requête sql de jointure interne car vous avez également appliqué un where
condition à la table la plus à droite sur cette jointure.