Bonjour,
J'utilise Hibernate 3.1.3 avec MySQL 5.0 and Oracle 9 et j'ai un problème avec une requête par l'exemple qui inclu des données historisées.
Je pense que mon contexte est un scénario classique. Mais, j'ai fait 2 jours recherche sur cet site et sur le Web sans trouver qelque chose qui m'aide vraiment.
J'ai des utilisateurs avec des postes dont l'évolution est enregistrée date par date.
Code:
table-> User id {pk}, name, ...
table-> position id {pk}, user_id {fk}, date, status, office, ...
Dans mon modèle l'objet User a une liste de Position mais seulment la plus récente est son poste courrant.
L'utilisateur final a un formulaire pour rechercher un utilisateur donné (donc un requête par l'example s'impose).
Malheureusement ce formulaire inclu de statut qui est historisé (seul le plus récent doit être pris en compte).
Je suisen train de me casser la tête sur ce problème pour completer ma requête Criteria par l'exemple...
En premier j'ai écris ceci :
Code:
Example ex = Example.create(user);
Criteria crit = session.createCriteria(User.class).add(ex);
crit.createCriteria("positions", "pos")
.add(Expression.eq("pos.status", userStatus);
Ca marche mais (comme c'était prévisible) ceal retourne le même utilisateur à chaque ligne de historique correspondante (même si ce n'est pas leposte leplus récent).
Voici le SQL (testé) que je cherche à traduire en Criteria :
Code:
SELECT u.*
FROM user u, position pos,
(SELECT user_id, MAX(date) AS last_date
FROM position GROUP BY user_id) last_pos
WHERE pos.user_id = last_pos.user_id
AND pos.date = last_pos.last_date;
AND u.id = pos.user_id
AND pos.status = ?
AND a.name = ?
... //ici les autres champs du formulaire
Donc, j'ai décide de définir un sous-requête pour obtenir de poste leplus récent.
Code:
DetachedCriteria subquery = DetachedCriteria.forClass(Position.class, "last_pos");
subquery.setProjection(
Projections.projectionList()
.add( Projections.max("last_pos.date"))
.add( Projections.groupProperty("last_pos.userAgent")
);
Example ex = Example.create(user);
Criteria crit = session.createCriteria(User.class).add(ex);
crit.createCriteria("positions", "pos")
.add(Property.forName("pos.date").eq(subquery))
.add(Expression.eq("pos.status", userStatus);
et j'ai obtenu l'exception suivante :
Quote:
java.lang.ClassCastException: org.hibernate.impl.CriteriaImpl$Subcriteria
at org.hibernate.criterion.SubqueryExpression.toSqlString(SubqueryExpression.java:43)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:333)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:67)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1514)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
...
Qu'est-ce que je n'ai pas bien fait ? (J'ai essayé tout un tas de variation de cela avec le même résultat)
Pour l'instant, je donne ma langue au chat.
Toute sorte d'aide, sugestions ou liens vers des exemples de code de sous-requêtes Criteria sont les bienvenus.
Merci
--
Frantz D.