2009-11-05 16 views
8

voglio aggiungere una sinistra unirsi sul tavolo TASK quando si verifica la seguente condizione: LEFT JOIN FETCH PROMPT p su (t.id = p.task.id e p.applicationName in ('XXX'))Hibernate HQL: come utilizzare un complesso sinistra join fetch

Ecco la mia interrogazione HQL:

select 
      distinct t   
     from 
      TASK t 
     LEFT JOIN FETCH 
      SERVER ser 
       on t.id=ser.task_id 
     LEFT JOIN FETCH 
      APPLICATION app 
       on ser.id=app.server_id   
     LEFT JOIN FETCH 
      PROMPT p on (t.id = p.task.id and p.applicationName in ('XXX')) 
     where 
      t.id=ser.task.id 
      and ser.id=app.server 
      and app.name in ('XXX') 
     order by t.id 

ottengo la seguente eccezione, probabilmente a causa di "on" parola chiave:

java.lang.NoSuchMethodError: org.hibernate.hql.antlr.HqlBaseParser.recover(Lantlr/RecognitionException;Lantlr/collections/impl/BitSet;)V 

     at org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:771) 

Qualche idea?

class Task { 
    private String taskId; 
    private Set<ServerDetails> servers; 
} 

class ServerDetails { 
    private String id; 
    private Set<ApplicationDetails> applications; 
} 

class ApplicationDetails { 
    private String id; 
} 

    Class Prompt { 
     private String applicationName; 
    } 

Come posso usare LEFT JOIN prendere usando la mia condizione p.applicationName in ('XXX')?

+0

La struttura di classe che hai pubblicato (presumo che ci siano annotazioni appropriate su tutte quelle proprietà) non collega il "Prompt" a nessun'altra classe. L'SQL unisce 'Prompt' e' Task' tramite 'task_id' ma non ci sono proprietà corrispondenti sopra. 'Task' una proprietà su' Prompt'? O vice versa? Puoi chiarire? – ChssPly76

risposta

23

Ci sono diversi problemi qui:

  1. tuo HQL come hai postato non è davvero HQL :-) E 'verso l'alto SQL. Per HQL è necessario utilizzare associazioni mappate per unire le tabelle. Vedi sotto per una versione migliorata.
  2. Per quanto a mia conoscenza la clausola ON non supporta più condizioni congiunte tra parentesi.
  3. NoSuchMethodError non è qualcosa che Hibernate genera :-) Probabilmente hai una versione precedente di antlr.jar da qualche parte nel classpath e viene prelevata al posto di quella prevista da Hibernate. Trovalo e rimuovilo.

Senza vedere le mappature che segue è probabilmente inesatta, ma prenderò una pugnalata a scrivere il HQL più appropriato:

select distinct t   
    from TASK t 
    left join fetch t.server ser 
    left join fetch ser.application app 
    left join t.prompt p with p.applicationName in ('XXX') 
order by t.id 

Nota che prompt non è inverosimile, perché non è possibile utilizzare join fetch insieme con la condizione with. È possibile sostituirlo con inner join fetch e where se è richiesta l'associazione.

Se i problemi persistono dopo che il problema del percorso di classe è stato risolto, sentiti libero di pubblicare i tuoi mapping se hai bisogno di aiuto con l'HQL reale.

+0

@ ChssPly76: Sono stupito di quanto bene tu conosca le interiora di Hibernate, suppongo che tu debba aver lavorato con esso fin dall'inizio, oppure che tu abbia effettivamente impegnato il codice nel progetto o entrambi: in entrambi i casi è bello averti qui per illuminare il codificatore si ammassa. –

+1

Ora, farai ingelosire Gavin. Ovviamente sto scherzando :-) - grazie. – ChssPly76

+0

Grazie per la risposta, ma ho ancora bisogno di recuperare prompt. Come posso usare left join ** fetch ** usando la mia condizione p.applicationName in ('XXX')? – Keren