2009-10-06 27 views
16

Załóżmy, że mam zajęcia takie jak:Hibernacja kryteria kwerendy o różnych właściwościach w różnych obiektach

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

class B { 
String getFoo(); 
} 

class C { 
int getBar(); 
} 

i chcę kryteriom na, dwa filtry na różnych właściwościach podklasie takich jak:

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

Co chcę zrobić, to połączyć kryteria B i kryteriaC za pomocą klauzuli "lub", coś w stylu:

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

Jak mogę to zrobić? Potykam się trochę nad API tutaj.

Odpowiedz

24

Zastosowanie aliases zamiast zagnieżdżonych kryteriów:

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

Aliasy są niepotrzebne. –

+0

Próbujesz tego - dzięki ponownie, Chess – RMorrisey

+0

Jak zrobiłbyś to bez aliasów? – RMorrisey

4

Wystarczy utworzyć jeden obiekt kryteria jak tak.

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

To nie działa; Wystąpił błąd typu: org.hibernate.QueryException: nie można rozwiązać właściwości: b.foo: com.myproject.A – RMorrisey

+0

Wygląda na to, że działa tylko z jednym poziomem właściwości, ale nie z rzeczywistym filtrem, którego używam. . – RMorrisey

+0

Musisz użyć createAlias ​​z createQuery. Odpowiednio zredagowałem odpowiedź. –

3

W przypadku gdy ktoś inny uzna za użyteczne, znalazłem bardziej skomplikowaną odpowiedź na problem, który wydaje się być akceptowane przez API, choć nie udało nam się przetestować go przed ChssPly pisał rozwiązanie jego (prostszy):

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

Ciekawe, nigdy nie myślałem, że spróbuję tego w ten sposób. Wynikowe zapytanie byłoby jednak zupełnie inne (i, być może, wolniejsze) od zapytania uzyskanego za pomocą aliasów. Ale może to być sposób na rozwiązanie problemu sqlRestriction, jeśli aliasy zawiodą. – ChssPly76

Powiązane problemy