Suppose I have some classes, like this:
OpA extends Operation
OpA1 extends OpA
OpA2 extends OpA
OpB extends Operation
OpB1 extends OpB
OpB2 extends OpB
OpB3 extends OpB
OpC extends Operation
Operation
|
/-----------------------------\
/ | \
OpA OpB OpC
/ |
/ |
/------\ /-----------\
/ \ / | \
OpA1 OpA2 OpB1 OpB2 OpB3
If I want to find some operations, I can do this:
session.createCriteria(Operation.class)
.add(...)
.add(...)
.addOrder(...)
.setFirstResult(...)
.setMaxResults(...)
.list();
But what if I want to apply these criteria not to all operations of type Operation.class
, but only to those of types: OpA2
+ OpB1
+ OpB3
+ OpC
?
My Question: How can I do it using Hibernate Criteria only? No HQL, please.
Note: I don't know if I should view this problem as "querying more than one class" (where all of them have fields with the same names as the ones I am querying), or if I view it as "restricting a query by a list of subclasses".
Edit: If I could create an interface TheOnesIWant
, and then make classes OpA2
, OpB1
, OpB3
and OpC
implement this interface, this would yield the result I want: session.createCriteria(TheOnesIWant.class)
But I can't do this, because I only know the classes I want to query at runtime. The above class hierarchy is just an example.
Criteria in Hibernate can be used for join queries by joining multiple tables, useful methods for Hibernate criteria join are createAlias(), setFetchMode() and setProjection() Criteria in Hibernate API can be used for fetching results with conditions, useful methods are add() where we can add Restrictions.
1.2. The Restriction class in hibernate provide several methods that can be used as conditions (also known as Criterion). These conditions are added to a criteria object with the add() method. This method takes an org. hibernate.
In general, Hibernate has very limited support for joining unrelated entities. By "unrelated" I mean entities that don't have references to each other. Critera API doesn't support it at all, and HSQL can do only cross join. Don't get me wrong, the underlying Criteria/HQL implementation is capable of joining unrelated entities, but the API do not expose this functionality. (You can do all kinds of joins (inner, left, right, full) on related entities.)
The only way to do inner/left/right/full join on unrelated entities, is native sql.
However, if the unrelated entities have common parent, you can use a hibernate feature called "implicit polymorphism": selecting the parent, will return parent and all its sub-classes. And then you can restrict the result to list of sub-classes.
So try this:
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Property.forName("class").eq(OpA2.class)
,Property.forName("class").eq(OpB1.class)
,Property.forName("class").eq(OpB3.class)
,Property.forName("class").eq(OpC.class)))
.list();
EDIT:
Here is a example how to query properties that do not exist in the parent class:
In this example properties "f" and "value" don't exist in the Operation class, they only exist in OpA2 abd OpC classes.
List<Operation> list = session.createCriteria(Operation.class)
.add(Restrictions.or(
Restrictions.and(Property.forName("class").eq(OpA2.class), Restrictions.eq("f", 1))
, Property.forName("class").eq(OpB1.class)
, Property.forName("class").eq(OpB3.class)
, Restrictions.and(Property.forName("class").eq(OpC.class), Restrictions.eq("value", "b"))))
.list();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With