2009-11-05 21 views
8

Chcę dodać LEFT JOIN na stole TASK gdy zachodzi następujący warunek: LEFT JOIN FETCH PROMPT na p (t.id = p.task.id i p.applicationName w ('XXX'))Hibernate HQL: jak korzystać z kompleksowego LEFT JOIN sprowadzić

Oto moje zapytania 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 

otrzymuję następujący wyjątek, prawdopodobnie ze względu na "on" słowo kluczowe:

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) 

Jakieś pomysły?

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; 
    } 

Jak mogę użyć LEFT JOIN sprowadzić używając mojego stanu p.applicationName w ('XXX')?

+0

Opublikowana przez ciebie struktura klas (zakładam, że są odpowiednie adnotacje na wszystkich tych właściwościach), nie łączy "Monitu" z żadną inną klasą. You SQL dołącza 'Prompt' i' Task' przez 'id_zadania', ale nie ma powyższych pasujących właściwości. Czy 'Task' jest właściwością w' Prompt'? Lub odwrotnie? Możesz wyjaśnić? – ChssPly76

Odpowiedz

23

Istnieje kilka problemów tutaj:

  1. Twój HQL jak już pisał to nie jest naprawdę HQL :-) To prosto SQL. W przypadku HQL do scalania tabel potrzebne są zmapowane skojarzenia. Poniżej znajduje się poprawiona wersja.
  2. O ile mi wiadomo, klauzula ON nie obsługuje wielu warunków połączonych w nawiasach.
  3. NoSuchMethodError nie jest czymś, co rzuciłby Hibernate :-) Prawdopodobnie masz starszą wersję antlr.jar gdzieś w swojej ścieżce klasowej i zostanie ona pobrana zamiast oczekiwanej przez Hibernate. Znajdź i usuń.

Nie widząc mapowania następujące prawdopodobnie niedokładne, ale wezmę ukłucie w pisaniu bardziej odpowiednim HQL:

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 

Zauważ, że prompt nie jest pobierany, ponieważ nie można używać join fetch razem z warunkiem with. Możesz go zastąpić inner join fetch i where, jeśli wymagane jest powiązanie.

Jeśli nadal masz problemy po rozwiązaniu problemu ze ścieżką klas, możesz wysłać swoje mapowania, jeśli potrzebujesz pomocy z aktualnym HQL.

+0

@ ChssPly76: Jestem zdumiony, jak dobrze znasz wnętrze Hibernate, przypuszczam, że musiałeś pracować z nim od samego początku, lub faktycznie kodujesz projekt lub oba - tak czy inaczej jego świetny fakt, że jesteś tutaj, by oświetlić masy koderów. –

+1

Teraz sprawisz, że Gavin będzie zazdrosny. Żartuję oczywiście :-) - dziękuję. – ChssPly76

+0

Dziękuję za odpowiedź, ale nadal muszę pobrać monit. Jak mogę użyć lewe sprzężenie ** pobierz ** używając mojego warunku p.applicationName w ("XXX")? – Keren