Trying again, join with a subclass, can you even do this in QDSL?

77 views
Skip to first unread message

Phil Scadden

unread,
Oct 27, 2016, 11:50:59 PM10/27/16
to Querydsl
What I would deparately like to generate is:
SELECT id,operator from BORE INNER JOIN WaterBore ON Bore.id = WaterBore.id where drawer like "council%";

Water bore however is subclass of bore, viz

have entity with joined inheritance subclass vis
@QueryEntity
@Entity(name = "Bore")
...
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE_ID", discriminatorType = DiscriminatorType.INTEGER)
public class Bore implements Serializable {
...
   Long id;
   String operator;
   .... ( a very long list)

and subclass
@QueryEntity
@Entity(name = "WaterBore")
...
public class WaterBore extends Bore{
   ..
    String drawer;

if I try to do this on the subclass
          QWaterBore boreHole = QWaterBore.waterBore;
          PathBuilder<WaterBore> entityPath = new PathBuilder<WaterBore>(WaterBore.class,"boreHole");
          StringPath path = entityPath.getString("drawer");
          Predicate wc = path.containsIgnoreCase("council");
          bhl = query.from(boreHole).where(wc).list(entityPath); // lets ignore the projection for the moment.

I get
java.lang.IllegalArgumentException: Undeclared path 'boreHole'. Add this path as a source to the query to be able to reference it.

so trying to do it with innerjoin. However, QWaterbore inherits from Bore and doesnt have the foreign key relationship. This cant be an unusual thing to do surely??

How are you supposed to this in QueryDSL??

Richard Richter

unread,
Oct 28, 2016, 7:40:01 AM10/28/16
to Querydsl
Hi

Everyday I learn something new - I never new how to get the field from Qclass by its name and PathBuilder can do that. :-) Too bad it does not have a simple constructor based on the actual entity base path, because if you could create it directly from your "boreHole" instance you'd be safe.

The trouble is that string parameter to PathBuilder (that is "boreHole" is not the same like the implicit name of the QWaterBore.waterBore variable (variable from Querydsl perspective, I just call them generally "aliases"). Just print that boreHole instance and it will probably say:
"waterBore". In your query you mix instance named "waterBore" and another one named "boreHole". So you:

- either change first like to: QWaterBore boreHole = new QWaterBore("boreHole")
- or change that string to "boreHole" in the constructor to: boreHole.toString()
- or... both actually! that way you will name the boreHole instance as you want AND you'll safely use the same name in the constructor.

Although I'm not sure how safe is that toString in the future (Timo would know better).

Hope it helps, you helped me with PathBuilder, because until today it still puzzled me how to get Path from Qclass by the property name. One can change the generation, but then you have only that "map-like" interface and not fields and I'd love to have both. There seems to be no way how to get to this using metamodel either (or is there?) and this PathBuilder seems to be rather quite around path - that's why we used reflection on the QClass to get the Field instnace representing the column/attribute.

I don't understand the rest of the question with inner join, but I hope it's not relevant after my point.

Cheers

Virgo

Phil Scadden

unread,
Oct 28, 2016, 4:28:59 PM10/28/16
to Querydsl
Thanks very much! That is massive insight into pathbuilder if nothing else. I will give it go - and yes, if I can make it work on subclass, then join is irrelvant.


Phil Scadden

unread,
Oct 30, 2016, 8:37:37 PM10/30/16
to Querydsl
yes, that worked and using toString() makes it easier to generalize as well. Whew!

Reply all
Reply to author
Forward
0 new messages