4

first of all, sorry if this question has already been asked, but I couldn't find any similar questions nor answers for my problem.

My problem is, that I have several subclasses in several hierarchy levels inheriting from one subclass.



    @Entity
    public class A{ }

    @Entity
    public class B extends A { ... }

    @Entity
    public class C extends A{ ... }

    @Entity 
    public class D extends C { 
        private String someAttribute; 
    }

    @Entity 
    public class E extends C { 
        private String anotherAttribute; 
    }

I need to process a query on C and get all entities from C,D,E according to my criteria, which accesses attributes from D and E.

I noticed, that it is not possible to access for example someAttribute fro D executing a query on C. like this:



    Root root = query.from(C.class);
    Path p = root.get("someAttribute");
    Path p2 = root.get("anotherAttribute");

Please note, that I cannot work with metamodels at this point.

In JPAQL I would code something like that:

`select e1 from C eq where someAttribute = .... or anotherAttribute = ....`

And it would resolve my hierarchy properly.

To solve the problem, I created my own annotation equivalent to @XmlSeeAlso and named it @PersistenceSeeAlso which tells me, which subclasses I have to look up to find my attribute. So when I process my hierarchy accoridng to @PersistenceSeeAlso and get my paths I need to create a new Root element for each subclass, that I look up for my attribute.

The main Problem here is, that query.form(clazz) creates a join on the query, which totally messes up my query, but I need a Root element on my type to resolve the path.

So my question is; is there a way, to handle multiple subclass selections with JPA2 CriteriaBuilder without creating new Root instances, maybe with EntityType?

Or am I doing something totally wrong?

Thank you very much in advance!

Best regards, Q

1 Answers1

1

sorry for the long wait!

That's a great question that I see all the time. The problem is that you are assuming information about the sub-types of C, which isn't exactly right.

If you use a "table per class" or "joined table" inheritance strategy, then the data for D and E are stored in separate tables and select e1 from C eq where someAttribute = .... or anotherAttribute = .... would not work, since those columns don't exist in C.

You would need to LEFT JOIN the columns from D and E onto C before you can filter. (I answered a similar question before that should help.

Community
  • 1
  • 1
logan
  • 3,416
  • 1
  • 33
  • 45