web-dev-qa-db-fra.com

Sous-requête JPA / hibernate dans la clause from

Nous utilisons JPA avec hibernate comme fournisseur, nous avons une requête qui contient une jointure avec une sous-requête dans la clause FROM, mais nous obtenons l'erreur suivante:

org.hibernate.hql.ast.QuerySyntaxException: jeton inattendu: (près de la ligne 1, colonne 75 [SELECT sd FROM com.hp.amber.datamodel.entities.analysis.SnapshotDates sd, (SELECT max (x.changeDate) maxChangeDate, x .viewId, x.state FROM com.hp.amber.datamodel.entities.analysis.SnapshotDates x WHERE x.changeDate <: date AND x.viewId in (: viewIds) AND x.state =: state GROUP BY x.viewId, x.state) sd2 OERE sd.viewId = sd2.viewId ET sd.state =: état ET sd.changeDate = sd2.maxChangeDate]

Voici la requête:

SELECT sd 
FROM SnapshotDates sd, 
     (SELECT max(x.changeDate) maxChangeDate, x.viewId, x.state 
      FROM SnapshotDates x
     WHERE x.changeDate<:date AND x.viewId in (:viewIds) AND x.state=:state
GROUP BY x.viewId, x.state) sd2
WHERE sd.viewId = sd2.viewId 
      AND sd.state = :state 
      AND sd.changeDate = sd2.maxChangeDate

Merci pour l'aide

21
gads

Je ne pensais pas que HQL pouvait faire des sous-requêtes dans la clause from

https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html#queryhql-subqueries

notez la phrase:

Notez que les sous-requêtes HQL ne peuvent se produire que dans les clauses select ou where.

J'imagine que vous pouvez le changer en une requête native et l'exécuter de cette façon.

27
dispake

Votre SQL est:

SELECT sd FROM SnapshotDates sd, (SELECT max (x.changeDate) maxChangeDate, x.viewId, x.state FROM SnapshotDates x WHERE x.changeDate <: date AND x.viewId in (: viewIds) AND x.state =: state GROUP BY x.viewId, x.state) sd2 WHERE sd.viewId = sd2.viewId ET sd.state =: état ET sd.changeDate = sd2.maxChangeDate

Vous pouvez réécrire votre sql comme

SELECT sd 
FROM SnapshotDates sd, 
WHERE sd.viewId in (:viewIds)
    AND sd.state = :state
    sd.changeDate = (SELECT max(x.changeDate) FROM SnapshotDates x WHERE x.viewId = ds.viewId AND x.state = ds.state)

Trouvez inspiré par l'exemple

SELECT m FROM Professor m WHERE (SELECT COUNT(e) FROM Professor e WHERE e.manager = m) > 0

http://www.Java2s.com/Code/Java/JPA/EJBQLWhereClauseWithSubQuery.htm

Mon exemple similaire, j'avais SQL

select k.* from kredits k, 
  (select client_id, max(r_date) r_date from kredits k group by client_id) k2 
where k.client_id = k2.client_id 
    AND k.r_date = k2.r_date 
order by k.id

Réécrivez-le pour PQL

select k From Kredit k
where k.rDate = (select MAX(k2.rDate) from Kredit k2 where k2.clientId = k.clientId)
order by k.id

Il sera traduit en

select kredit0_.id as id28_, kredit0_.client_id as client59_28_ from kredits kredit0_ 
where kredit0_.r_date=(select MAX(kredit1_.r_date) from kredits kredit1_ where kredit1_.client_id=kredit0_.client_id) 
order by kredit0_.id

retourne le même résultat que SQL.

Utilisez Hebirnate 3.3.1 avec MySQL 5.0.24

4
victorq10