Je vais avoir un problème avec une requête HQLavec "select new Object ... rejoindre ... où"
Trois classes
ClassOne est mon BusinessObject
public class ClassOne {
private int id;
private int status;
private Set<ClassTwo> classTwos;
+ other fields/getters/setters/constructor etc
}
ClassTwo est référencé dans un ensemble de ClassOne et est en quelque sorte de l'histoire d'un objet de ClassOne
public class ClassTwo {
private int id;
private int oldStatus;
private int newStatus;
private String message;
//+ getters/setters/constructor etc
}
ClassThre e est ma DTO/VO avec un seul classTwo (pas la histoire)
public class ClassThree {
private int id;
private int status;
private ClassTwo classTwo;
public ClassThree(int pId, int pStatus, ClassTwo pClassTwo) {
id=pId;
status=pStatus;
classTwo=pClassTwo;
}
//+ getters/setters etc
}
Maintenant, je voudrais créer une requête HQL comme ceci:
J'aimerais obtenir tous les objets de ClassThree avec certain statut et s'il existe le plus récent ClassTwo avec un certain newStatus.
Par exemple:
Je voudrais obtenir tous les DTOs (ClassThree) de ClassOne dont le statut est maintenant 1, mais plus tôt dans leur histoire il a été 2 et j'aimerais avoir le dernier objet ClassTwo qui a 2 comme newStatus.
SELECT new ClassThree(c1.id, c1.status, c2)
FROM ClassOne c1
LEFT JOIN c1.classtwos c2 (...)
et (...) est là, je ne sais pas quoi faire, je ne suis même pas sûr que ce soit une jointure/join fetch
regardé autour et déjà essayé beaucoup, mais aucune idée. Surtout avec la recherche de jointure je reçois quelques erreurs Hibernate comme org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
.
Récupérer l'BusinessObject comme ça est pas un problème
SELECT distinct(c1)
FROM ClassOne c1
LEFT OUTER JOIN FETCH c1.classtwos c2
et je reçois les ClassTwos comme mon champ.
Merci à l'avance,
Jacob
P.S .: Une chose pourrait être important, ClassTwo n'a pas de référence à ClassOne !!
PPS: La simple requête SQL qui résout mon problème semble plus ou moins comme ça:
select * from classone as c1 left join (select * from classtwo where newstatus = 2) c2 on c1.id=c2.id_classone whete c1.status = 1
Cette requête fonctionne et obtient toutes les informations nécessaires sur mon PostGreSQL DB, mais je voudrais vraiment avoir un HQL de continuer à travailler avec, en particulier pour des raisons de maintenance et ainsi de suite ...
Mise à jour avec une solution de contournement:
Obtenir les ids de tous les ClassOnes avec un état 1
Collection<Integer> ids = null;
ids = (Collection<Integer>) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session pSession) throws HibernateException, SQLException {
return getDocumentIds(pSession, pStatus);
}
}
);
Maintenant je tous les DTO qui sont en état 2 (grâce à Ivan) avec:
requête nommée Document.dto.with.transfert
SELECT new DocumentDTO(d.id, d.status, histo)
FROM Document d
LEFT JOIN d.histories histo
WHERE
d.id in (:ids)
AND
(histo.id =
SELECT MAX(innerhisto.id)
FROM Document innerd
JOIN innerd.histories innerhisto
WHERE d.id = innerd.id AND innerhisto.newStatus = 21)
(dans mon code que j'utilise des requêtes nommées)
List<DocumentDTO> lRes = new ArrayList<DocumentDTO>();
Query lQuery = getSession(false).getNamedQuery("Document.dto.with.transfer");
lQuery.setParameterList("ids", ids);
lResultList.addAll(lQuery.list());
ensuite supprimer toutes les ID déjà trouvés de ma liste ids
for (DocumentDTO dto : lResultList) {
ids.remove(dto .getId());
}
Je fais une troisième requête utiliser un second constructeur pour le DTO, en initialisant mon histoire avec un objet factice.
requête nommée Document.dto.simple
SELECT new DocumentDTO(d.id, d.status)
FROM Document d
WHERE
d.id in (:ids)
(une autre requête nommée)
lQuery = getSession(false).getNamedQuery("Document.dto.simple");
lQuery.setParameterList("ids", ids);
lResultList.addAll(lQuery.list());
et il est fait.
Vous utilisez Java et NHibernate ensemble? Je pensais que NHibernate était pour .NET? –
Non, juste étiqueté faux, en fait son Java + Hibernate – jacob
Je ne comprends pas les critères pour récupérer un c2 unique de votre description. –