2013-11-27 21 views
8

Tôi đang sử dụng Hibernate 3.6 và MSSQL 2012.HQL ngầm tham gia trong mệnh đề where tạo chéo tham gia thay vì bên tham gia

Khi thực hiện HQL này

select tbl.state from Property tbl where tbl.state = 1 and tbl.entity.state = 1 and 
tbl.entity.className = 'com....' and tbl.fieldName = 'fieldName' 

tôi nhận được lệnh SQL này

select property0_.State as col_0_0_ from Properties property0_ cross join Entities 
entity1_ where property0_.refEntityid=entity1_.id and property0_.State=1 and 
entity1_.State=1 and entity1_.ClassName='com....' and property0_.FieldName='fieldName' 

* Chú ý rằng tham gia chéothêm điều kiện vào mệnh đề where.

Theo tài liệu Hibernate https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql-joins-forms

ngầm tham gia nên tạo để bên tham gia.

Tôi nhận thấy rằng có một lỗi mở https://hibernate.atlassian.net/browse/HHH-7707 có thể đề cập đến vấn đề này nhưng không ai trả lời và nó đã được mở trong một năm rồi.

Tôi sẽ đánh giá cao bất kỳ thông tin nào về vấn đề này. Cảm ơn bạn.

PS. Tôi biết rằng việc sử dụng các kết nối ngầm không phải là cách viết đúng HQL nhưng tôi không thể làm bất cứ điều gì về điều này ngay bây giờ.

+1

Wow, điều này thực sự thực sự lame và bị hỏng trên một phần của hibernate. 'trong đó foo.bar không phải là null hoặc foo.bar.baz = x' trả về kết quả không hoàn toàn không logic nếu tất cả các đối tượng foo có tham chiếu thanh rỗng ... – Gus

Trả lời

9

bạn tham gia là một bên tham gia, nhưng bằng cách sử dụng cú pháp cũ bao gồm trong việc thêm một điều kiện trong mệnh đề where:

where property0_.refEntityid=entity1_.id 

thay vì làm việc đó với

inner join Entities entity1_ on property0_.refEntityid=entity1_.id 

Kết quả là chính xác tương tự.

Và sử dụng tham gia ngầm trong HQL không phải là một vấn đề gì cả, miễn là bạn hiểu những gì họ đang làm.

+0

Mọi thứ bạn nói đều ổn nhưng nó không giải thích tại sao tôi ' m nhận được tham gia chéo + thêm nơi điều kiện thay vì tham gia bên trong bình thường như các tài liệu nói. – Rotem

+1

Sau khi đọc câu trả lời của bạn, tôi đã quay trở lại phần "Hình thức tham gia cú pháp" trong tài liệu ngủ đông và đọc lại nó vài lần. Bây giờ tôi bắt đầu nhận ra rằng thuật ngữ "nối bên trong" được sử dụng ở đó, không cần thiết có nghĩa là cú pháp nối bên trong mà chỉ cho phép nối bên trong có thể được thực hiện theo hai cách, nối bên trong hoặc nối chéo với mệnh đề where where . Vì vậy, bây giờ, tôi có thể lấy lại để ăn, ngủ và tắm và để cho nó đi. Cảm ơn bạn @ jb-nizet – Rotem

+0

Để biết thông tin, tôi đã tham gia chéo ba với mệnh đề where được thêm vào, sau khi kiểm tra EXPLAIN, tôi có thể xác nhận tôi có cùng một kế hoạch thực thi. Tôi hoảng sợ một chút khi tôi thấy một số bài viết khác nói về những người tạo ra chéo tham gia bởi hibernate là xấu và đã thay đổi yêu cầu tiêu chí của họ ... cho không có gì trong thực tế, may mắn tôi đã kết thúc ở đây :-) – Walfrat

0

Khi sử dụng HQL, luôn luôn sử dụng bí danh thích hợp khi thực hiện tham gia truy vấn operations.Your nên một cái gì đó như thế:

select tbl.state 
from Property tbl 
left join tbl.entity entity 
where tbl.state = 1 
    and entity.state = 1 
    and entity.className = 'com....' 
    and tbl.fieldName = 'fieldName' 

Nếu không, nếu bạn cố gắng sử dụng tbl.entity.someProperty, trong HQL, nó sẽ luôn luôn tạo ra một crossJoin

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