2012-07-27 5 views
0

J'utilise Struts + Spring + Hibernate et j'ai du mal à faire fonctionner correctement ma HQL.Problème avec les jointures internes dans Hibernate (HQL)

J'ai quatre objets, objectA, objectB, objectC et objectD. L'objet A a une relation un à plusieurs avec l'objet B, et ils sont liés comme ObjectB a un FK ObjectA.Id. Ce modèle continue à travers les objets, c'est-à-dire que l'objet B a une relation un-plusieurs avec l'objet C, etc.

Ce que j'ai fait en ce moment appelle "FROM ObjectXVO WHERE objectXId =?" pour obtenir une liste d'objets. Mon application devient de plus en plus compliquée alors j'ai besoin de faire un HQL plus compliqué. Essentiellement, ce dont j'ai besoin, c'est que, étant donné ObjectBVO.objectBId, je dois retourner certaines colonnes de l'ObjectA qui a l'ObjectB donné, certaines colonnes des ObjectCs qui font partie de l'ObjectB donné, et toutes les colonnes des ObjectDs qui sont une partie des ObjectC faisant partie des ObjectBs donnés.

Ceci est ma déclaration SQL que j'utilise dans Microsoft SQL Server. Cela fonctionne et j'espère démontrer mon modèle.

SELECT ObjectB.ObjectBID, ObjectB.ObjectBName, ObjectC.ObjectCDescription, 
ObjectD.*, ObjectA.ObjectAID 
FROM ObjectB, ObjectC, ObjectD, ObjectA 
WHERE ObjectB.ObjectBID = 2 
AND ObjectA.ObjectAID = ObjectB.ObjectAID 
AND ObjectB.ObjectBID = ObjectC.ObjectBID 
AND ObjectD.ObjectCID = ObjectC.ObjectCID 

C'est le code dans l'objet DAOimpl je tente d'utiliser pour retourner Liste < ObjectDVO>

List<ObjectDVO> objectDs; 
try{ 
String hql = "SELECT ObjectBVO.objectBId, ObjectBVO.objectBName, 
    ObjectCVO.objectCDescription, ObjectCVO.objectCId," 
+" ObjectAVO.objectAId, ObjectAVO.objectAName, ObjectDVO" 
    +" FROM ObjectBVO, ObjectAVO, ObjectCVO, ObjectDVO" 
    +" WHERE ObjectBVO.objectBId = ?" 
+" AND ObjectAVO.objectAId = ObjectBVO.objectAId" 
+" AND ObjectBVO.objectBId = ObjectCVO.objectBId" 
+" AND ObjectDVO.objectCId = ObjectCVO.objectCId"; 
objectDs = getHibernateTemplate().find(hql, objectBID); 
} 

Cela jette juste une erreur disant nulle. J'ai regardé la documentation de HQL et quelques tutoriels mais ce n'est pas vraiment clair comment faire plus d'objets VO multiples. Quelqu'un peut-il aider? Merci.

Répondre

1

Vous devez affecter des alias à vos entités et renvoyer/utiliser ces alias. De plus, compte tenu de votre description, vous devriez avoir des associations OneToMany/ManyToOne entre vos entités, mais vous n'avez rien de tel. Tout ce que vous avez, ce sont des identifiants qui pointent vers d'autres entités.

Une requête qui renvoie plusieurs champs de ce type ne retournera pas d'instances de ObjectDVO. Il renverra un List<Object[]>, où chaque Object[] contiendra l'une des valeurs renvoyées par la requête: objectBId à l'index 0, objectBName à l'index 1, etc.

Enfin, un VO n'est pas une entité. Vos entités ne devraient pas être nommées VO. C'est comme ajouter un suffixe Fruit sur Animaux.

Quoi qu'il en soit, si vous gardez les entités comme indiqué (que vous ne devriez pas faire, mais introduire des associations à la place), votre requête devrait ressembler à ceci:

select b.objectBId, b.objectBName, c.objectCDescription, c.objectCId, 
     a.objectAId, a.objectAName, d 
from ObjectBVO b, ObjectAVO a, ObjectCVO c, ObjectDVO d 
where b.objectBId = ? 
and a.objectAId = b.objectAId 
and b.objectBId = c.objectBId 
and d.objectCId = c.objectCId 

avec les associations ManyToOne, vous pouvez simplement faire

select d from D d 
inner join fetch d.c c 
inner join fetch c.b b 
inner join fetch b.a a 

et vous obtiendriez un List<D>. Sur chaque instance D, vous pouvez le faire

String nameOfA = d.getC().getB().getA().getName(); 

Dernière remarque: une propriété fait partie d'une classe. Donc en nommant objectAId l'ID de ObjectA est redondant. Nommez-le id: objectA.getId() est beaucoup plus lisible que objectA.getObjectAId().

+0

Merci pour la bonne réponse!Je vais essayer cela et marquer comme une réponse si je peux le faire fonctionner. – user1287523

+0

fonctionne à merveille – user1287523