Hibernate criteria for querying more than one class (or subclass list constraints)

Suppose I have some classes like:

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 type operations Operation.class

, but only to types: OpA2

+ OpB1

+ OpB3

+ OpC

?

My question is, how do I go about doing this using only Hibernate criteria? No HQL please.

Note. I don't know if I should consider this issue as "requesting more than one class" (where they all have fields with the same names as the ones I am requesting), or if I consider it as "limiting the request to a list of subclasses".

Edit: If I could create an interface TheOnesIWant

and then make classes OpA2

, OpB1

, OpB3

and OpC

implement this interface, it will give the result I want: session.createCriteria(TheOnesIWant.class)

I can not do that, because I know the only classes that I want to query the runtime . The above class hierarchy is just an example.

+3


source to share


1 answer


In general, Hibernate has very limited support for merging unrelatedobjects. By "unrelated" I mean objects that have no references to each other. The Critera API doesn't support it at all and HSQL can only do cross-connect. Don't get me wrong, the underlying Criteria / HQL implementation is capable of attaching to unrelated objects, but the API does not expose this functionality. (You can do all kinds of joins (inner, left, right, full) on related objects.) The only way to do an inner / left / right / full join on unrelated objects is with native sql. However, if the unrelated objects have a common parent, you can use a hibernate feature called "implicit polymorphism": select the parent, return the parent and all of its subclasses. And then you can limit the result to a list of subclasses.
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:
Below is an example of requesting properties that do not exist in the parent class: In this example, the properties "f" and "value" do not exist in the Operation class, they only exist in the 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();

      

+5


source







All Articles