2009-11-05 39 views
8

Tôi muốn thêm một trái tham gia vào bảng TASK khi điều kiện sau đây xảy ra: LEFT JOIN FETCH p PROMPT trên (t.id = p.task.id và p.applicationName trong ('XXX'))Hibernate HQL: làm thế nào để sử dụng một trái phức tạp join lấy

đây là truy vấn HQL tôi:

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 

tôi nhận được ngoại lệ sau đây, có lẽ do "trên" keyword:

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) 

Bất kỳ ý tưởng nào?

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

Làm thế nào tôi có thể sử dụng trái join lấy sử dụng điều kiện p.applicationName tôi trong ('XXX')?

+0

Cấu trúc lớp bạn đã đăng (Tôi giả sử có chú thích thích hợp trên tất cả các thuộc tính đó) không liên kết 'Lời nhắc' với bất kỳ lớp nào khác. Bạn SQL tham gia 'Prompt' và' Task' qua 'task_id' nhưng không có thuộc tính nào phù hợp ở trên. 'Task' là thuộc tính trên' Prompt'? Hoặc ngược lại? Bạn có thể làm rõ? – ChssPly76

Trả lời

23

Có một số vấn đề ở đây:

  1. HQL của bạn như bạn đã đăng nó không phải là thực sự HQL :-) Đó là thẳng lên SQL. Đối với HQL, bạn cần sử dụng các liên kết ánh xạ để nối các bảng. Xem bên dưới để biết phiên bản cải tiến.
  2. Theo như tôi biết, mệnh đề ON không hỗ trợ nhiều điều kiện được kết hợp trong dấu ngoặc đơn.
  3. NoSuchMethodError không phải là một cái gì đó Hibernate sẽ ném :-) Bạn có thể có một phiên bản cũ của antlr.jar ở đâu đó trong classpath của bạn và nó được chọn ở vị trí mong đợi của Hibernate. Tìm và xóa nó đi.

Nếu không nhìn thấy ánh xạ của bạn sau đây là khả năng không chính xác, nhưng tôi sẽ mất một đâm vào văn bản cho HQL thích hợp hơn:

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 

Lưu ý rằng prompt là không lấy vì bạn không thể sử dụng join fetch cùng với điều kiện with. Bạn có thể thay thế bằng inner join fetchwhere nếu yêu cầu liên kết.

Nếu bạn vẫn gặp sự cố sau khi vấn đề về classpath được giải quyết, vui lòng đăng ánh xạ của bạn nếu bạn cần trợ giúp với HQL thực tế.

+0

@ ChssPly76: Tôi rất ngạc nhiên về việc bạn biết được Hibernate như thế nào, tôi phỏng đoán bạn phải làm việc với nó ngay từ khi thành lập hoặc bạn thực sự cam kết mã dự án hoặc cả hai. khối lượng coder. –

+1

Bây giờ, bạn sẽ khiến Gavin ghen tị. Tôi đang đùa tất nhiên :-) - cảm ơn. – ChssPly76

+0

Cảm ơn bạn đã trả lời nhưng tôi vẫn cần tìm nạp lời nhắc. Làm cách nào tôi có thể sử dụng tham gia bên trái ** tìm nạp ** bằng cách sử dụng điều kiện p.applicationName của tôi trong ('XXX')? – Keren

Các vấn đề liên quan