hibernate - QueryDSL generates cross join -
i looking offer content filtering results. (edited brevity) entities following:
node:
@entity @inheritance(strategy = inheritancetype.joined) public abstract class node { @id @generatedvalue public integer id; }
scene:
@entity public class scene extends node { @onetomany(mappedby = "scene", /*fetch = fetchtype.eager, */cascade = cascadetype.all) public list<source> sources; }
source:
@entity public class source extends node { @manytoone public scene scene; @enumerated(enumtype.ordinal) public sourcetype type; }
what follows example of filter wish implement.
given collection of sourcetypes wish select scenes such scene referred source of each 1 of types. achieve using querydsl following predicate:
private predicate filterbysourcetype(collection<sourcetype> it) { booleanbuilder bb = new booleanbuilder(); (sourcetype st : it) bb.and(qscene.scene.sources.any().type.eq(st)); return bb.getvalue(); }
a series of these predicates combined give overall query. when selecting 1 sourcetype resulting query looks so:
hibernate: select count(scene0_.id) col_0_0_ scene scene0_ inner join node scene0_1_ on scene0_.id=scene0_1_.id exists (select 1 source source1_ inner join node source1_1_ on source1_.id=source1_1_.id (source1_.id in (select sources2_.id source sources2_ inner join node sources2_1_ on sources2_.id=sources2_1_.id scene0_.id=sources2_.scene_id)) , source1_.type=?)
i believe happens above cross join , result (2k scenes, 1k sources) query takes multiple seconds.
i tried switching concrete class polymorphism eliminate node joins no noticeable performance improvement.
how optimise predicate?
turns out can use jpasubquery collectionexpression , write out query how write plain old sql.
bb.and(qscene.scene.in( new jpasubquery() .from(source) .where(source.type.eq(st)) .list(source.scene) ));
Comments
Post a Comment