2009-10-06 36 views
16

Giả sử tôi có các lớp học như:Hibernate tiêu chí truy vấn trên các thuộc tính khác nhau của các đối tượng khác nhau

class A { 
B getB(); 
C getC(); 
} 

class B { 
String getFoo(); 
} 

class C { 
int getBar(); 
} 

và tôi muốn lọc các tiêu chí về A, hai bộ lọc trên các thuộc tính lớp con khác nhau, như:

Criteria criteriaA = session.createCriteria(A.class); 
Criteria criteriaB = criteriaA.createCriteria("b").add(Restrictions.eq("foo", "Something")); 
Criteria criteriaC = criteriaA.createCriteria("c").add(Restrictions.eq("bar", 0)); 

Những gì tôi muốn làm là kết hợp các tiêu chíB và tiêu chíC sử dụng mệnh đề "hoặc", như sau:

//this does not work 
criteriaA.add(Restrictions.disjunction().add(criteriaB).add(criteriaC)); 

Làm cách nào để thực hiện điều này? Tôi đang vấp ngã một chút về API ở đây.

Trả lời

24

Sử dụng aliases thay vì tiêu chí lồng nhau:

Criteria criteria = session.createCriteria(A.class) 
.createAlias("b", "b_alias") 
.createAlias("c", "c_alias") 
.add(Restrictions.disjunction() 
    .add(Restrictions.eq("b_alias.foo", "Something")) 
    .add(Restrictions.eq("c_alias.bar", "0")) 
); 
+0

Bí danh là không cần thiết. –

+0

Thử điều này - cảm ơn lần nữa, Cờ vua – RMorrisey

+0

Bạn sẽ làm điều này như thế nào nếu không có bí danh? – RMorrisey

4

Bạn chỉ cần tạo một tiêu chí đối tượng như vậy.

Criteria criteria = session.createCriteria(A.class); 
criteria.add(Restriction.disjunction() 
    .add(Restriction.eq("b.foo", "something")) 
    .add(Restriction.eq("c.bar", 0))); 
+0

Điều này không hoạt động; Tôi nhận được một lỗi như: org.hibernate.QueryException: không thể giải quyết thuộc tính: b.foo của: com.myproject.A – RMorrisey

+0

Có vẻ như điều này sẽ chỉ hoạt động với một mức thuộc tính, nhưng không phải cho bộ lọc thực mà tôi đang sử dụng . – RMorrisey

+0

Bạn phải sử dụng createAlias ​​của createQuery. Tôi đã chỉnh sửa câu trả lời cho phù hợp. –

3

Trong trường hợp ai đó tìm thấy nó hữu ích, tôi tìm thấy một câu trả lời phức tạp hơn cho vấn đề mà dường như được cho phép bởi các API, mặc dù tôi đã không nhận được để kiểm tra nó trước khi ChssPly posted mình (đơn giản) giải pháp:

DetachedCriteria bValues = DetachedCriteria.forClass(A.class); 
bValues.createCriteria("b").add(Restrictions.eq("foo", "something")); 

DetachedCriteria cValues = DetachedCriteria.forClass(A.class); 
cValues.createCriteria("c").add(Restrictions.eq("bar", 0)); 

Restrictions.or(Subqueries.in("id", bValues), Subqueries.in("id", cValues)); 
+0

Thú vị, tôi chưa bao giờ nghĩ thử nó theo cách này. Truy vấn kết quả sẽ khá khác nhau (và, có thể, chậm hơn) từ truy vấn thu được qua các bí danh. Nhưng đây có thể là cách để giải quyết vấn đề sqlRestriction của bạn nếu các bí danh thất bại. – ChssPly76

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