2010-10-05 23 views
3

Pourquoi la requête HQL suivante échoue-t-elle?Pourquoi cette suppression HQL échoue-t-elle, lorsqu'une sélection HQL avec les mêmes termes fonctionne?

string hql = @"delete MyLog log 
       where 
        log.UtcTimestamp < :threshold and 
        log.Configuration.Application = :application"; 

session.CreateQuery(hql) 
     .SetDateTime("threshold", threshold) 
     .SetEnum("application", this.application) 
     .ExecuteUpdate(); 

la même forme de requête fonctionne lorsqu'il est utilisé dans un select:

string hql = @"from MyLog log 
       where 
        log.UtcTimestamp < :threshold and 
        log.Configuration.Application = :application"; 
IList<MyLog> log = session.CreateQuery(hql) 
    .SetDateTime("threshold", threshold) 
    .SetEnum("application", this.application) 
    .List<MyLog>(); 

Le mappage pour MyLog contient:

References(x => x.Configuration) 
    .Columns("CONFIGURATION_ID") 
    .ReadOnly();  

Le mappage de configuration contient:

Map(x => x.Application, "APPLICATION_ID"); 

L'erreur que j'obtiens est:

supprimer mylog, CONFIGURATION countercon1_ où UTC_TIMESTAMP <: p0 et APPLICATION_ID =: p1; : = p0 04/10/2010 17:15:52,: p1 = 7

NHibernate.Exceptions.GenericADOException: ne pouvait pas exécuter la requête de mise à jour [SQL:

supprimer mylog, CONFIGURATION countercon1_ où UTC_TIMESTAMP <? et APPLICATION_ID =?

] ---> Oracle.DataAccess.Client.OracleException: ORA-00933: commande SQL pas correctement terminé

+1

http://docs.jboss.org/hibernate/stable /core/reference/fr/html/batch.html#batch-direct – rebelliard

+0

Pouvez-vous essayer http://www.codepaste.net/nmrne1? Ou peut-être http://www.codepaste.net/q5m8on? Il serait également rock si vous avez utilisé http://nhprof.com/ – rebelliard

+1

+ 1. Merci Fafael. Il semble que le problème puisse être: "Aucune jointure, implicite ou explicite, ne peut être spécifiée dans une requête HQL en bloc. Les sous-requêtes peuvent être utilisées dans la clause where, où les sous-requêtes elles-mêmes peuvent contenir des jointures. ' –

Répondre

5

Essayez ceci:

delete MyLog log 
where log.id in 
      (select l.id 
      from MyLog l 
      where l.UtcTimestamp < :threshold and 
      and.Configuration.Application = :application) 
+0

Je viens de revenir à ce problème et votre réponse a fonctionné la première fois :) –

2

La syntaxe est DELETE FROM MyLog ....

avoir à l'esprit que HQL supprimer ne ne pas honorer les cascades définies avec (n) les mises en correspondance hibernate.

Vous pouvez donc sélectionner toutes les entités et les supprimer une par une.

+0

On dirait que le FROM est facultatif ... –

+0

@Thomas Le FROM est en effet facultatif lors de l'utilisation de [opérations de style DML] (http://docs.jboss.org/hibernate/stable/core/reference/en/html/batch.html#batch-direct). –