2009-11-03 8 views
1

J'ai une requête qui fonctionne en SQL normal, mais qui ne fonctionne pas sur JPA et ne peut pas comprendre pourquoi. Comme vous pouvez le deviner à partir du titre, j'ai un indice mais je ne sais pas comment le "réparer".Colonne de jointure JPA avec des valeurs nulles

Voici le code réelles importantes:

@Id 
@Basic(optional = false) 
@Column(name = "id", nullable = false) 
private Integer id; 

@Basic(optional = false) 
@Column(name = "read_permission", nullable = false) 
private boolean readPermission; 

@Basic(optional = false) 
@Column(name = "write_permission", nullable = false) 
private boolean writePermission; 

@Basic(optional = false) 
@Column(name = "execute_permission", nullable = false) 
private boolean executePermission; 

@Basic(optional = false) 
@Column(name = "admin_permission", nullable = false) 
private boolean adminPermission; 

@JoinColumn(name = "xinco_core_data_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreData xincoCoreDataId; 
@JoinColumn(name = "xinco_core_group_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreGroup xincoCoreGroupId; 

@JoinColumn(name = "xinco_core_node_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreNode xincoCoreNodeId; 

@JoinColumn(name = "xinco_core_user_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreUser xincoCoreUserId; 

Et voici le sql travail:

select * from xinco_core_ace where xinco_core_user_id = 1 order by xinco_core_user_id, xinco_core_node_id, xinco_core_data_id; 

Et voici ce que j'essaie de faire:

SELECT xca FROM XincoCoreAce xca WHERE xca.xincoCoreUserId.id = 1 ORDER BY xca.xincoCoreUserId.id, xca.xincoCoreGroupId.id, xca.xincoCoreNodeId.id, xca.xincoCoreDataId.id 

La question, Je pense, est que le xca.xincoCoreUserId.id, xca.xincoCoreGroupId.id, xca.xincoCoreNodeId.id, xca.xincoCoreDataId.id peut être nul ls.

Une idée? J'espère que c'est plus facile à lire: P

+0

De manière générale, faire un vidage de code dans une question est une mauvaise idée. Vous devriez réduire ce code au strict minimum pour démontrer le problème. Si c'est plus facile à lire et à comprendre (et donc c'est beaucoup plus susceptible d'être lu et répondu) et, si rien d'autre, cela démontre que vous avez fait des efforts. – cletus

+0

Merci pour les commentaires, c'est juste ma deuxième question et le premier avec le code correspondant. l'espoir est plus propre maintenant. – javydreamercsw

Répondre

1

Aussi me est arrivé avec une requête plus simple:

select t from Task t where t.worker is not null order by t.worker.normalizedName 

Constaté que toute entité de résultat de tâche dans laquelle le travailleur de l'attribut est nulle (la tâche est non affectée) sera mis au rebut. Plus tard, j'ai découvert que c'est parce que la navigation dans JPA est faite en utilisant des jointures internes (la spécification le dit) et cela exclut tout résultat où une partie du chemin est nulle.

Ce rapport de bogue décrit avec précision le problème :

https://bugs.eclipse.org/bugs/show_bug.cgi?id=363798

Malheureusement, ce n'est pas un bug de mise en œuvre et vous devrez factoriser vos entités/requêtes pour éviter ce genre de situations.

0

Je ne suis pas un expert JPA ici, mais j'essayerais d'obtenir le SQL réel qui est exécuté sur la base de données. Peut-être que le FetchType.LAZY a quelque chose à voir avec le problème?

+0

Si vous utilisez Hibernate en tant que votre fournisseur JPA, vous pouvez jeter un oeil à http://www.javalobby.org/java/forums/t44119.html Il est un peu vieux, donc j'espère que cela fonctionne toujours. – kovica

+0

J'utilise EclipseLink mais je vais jeter un coup d'oeil de toute façon. – javydreamercsw

+0

C'est la requête réelle effectuée (en utilisant la journalisation eclipselink): SELECT t1.id, t1.write_permission, t1.admin_permission, t1.execute_permission, t1.read_permission, t1.xinco_core_user_id, t1.xinco_core_data_id, t1.xinco_core_group_id, t1.xinco_core_node_id FROM xinco_core_data t4, xinco_core_node t3, xinco_core_group t2, xinco_core_ace t1, xinco_core_user t0 O (((t3.id =?) ET ((((t3.id = t1.xinco_core_node_id) ET (t0.id = t1.xinco_core_user_id)) ET (t2.id = t1.xinco_core_group_id)) ET (t4.id = t1.xinco_core_data_id))) ORDER BY t0.id ASC, t2.id ASC, t3.id ASC, t4.id ASC bind => [1] – javydreamercsw

1

Ceci est la requête réelle effectuée (en utilisant l'enregistrement de EclipseLink):

SELECT t1.id, t1.write_permission, t1.admin_permission, t1.execute_permission, t1.read_permission, t1.xinco_core_user_id, t1.xinco_core_data_id, t1.xinco_core_group_id, t1.xinco_core_node_id FROM xinco_core_data t4, xinco_core_node t3, xinco_core_group t2, xinco_core_ace t1, xinco_core_user t0 WHERE ((t3.id = ?) AND ((((t3.id = t1.xinco_core_node_id) AND (t0.id = t1.xinco_core_user_id)) AND (t2.id = t1.xinco_core_group_id)) AND (t4.id = t1.xinco_core_data_id))) ORDER BY t0.id ASC, t2.id ASC, t3.id ASC, t4.id ASC bind => [1] 

Pour une raison quelconque ayant l'ordre par ajoute beaucoup de la table où ayant des recoupements nulls font le résultat sortir vide.

Enlever la commande en obtenant le résultat requis (en panne bien sûr).

Voir cette EclipseLink bug

Questions connexes