Hi,
I'm trying to build a dynamic query with PathBuilder but I
have problems with Joins/Alias which seems to result from my
understanding of Expressions.path.
In the following I have simplified my entity model to highlight the problem.
But lets start with the expected query...
I'm debugging the query generated by queryDSL in AbstractJPAQuery:100.
Here i would expect to get the following query:
select root.id
from Root root
inner join root.innerRoots as innerRoots
inner join innerRoots.childs as innerRootChilds
inner join root.childs as rootChilds
where innerRootChilds.someProperty = ?1 and rootChilds.someOtherProperty > ?2
I have 2 different problems:
Either I don't get the alias right because the property name of my entities implicitly is taken as alias resulting in:
select root.id
from Root root
inner join root.innerRoots as innerRoots
inner join innerRoots.childs as childs
inner join root.childs as childs
where childs.someProperty = ?1 and childs.someOtherProperty > ?2
Or the join is wrong resulting in an dereferencing error:
select root.id
from Root root
inner join root.innerRoots
inner join root.innerRoots.childs
inner join root.childs
where root.innerRoots.childs.someProperty like ?1 and root.childs.someOtherProperty like ?2
The code I use to generate this query is a bit complicated (as the entity model is more complicated).
It
seems to me, that my understanding of PathBuilder and Joins is
completely wrong, so maybe someone can give me a hint, how these should
be used in this context (using my simplified entity model below).
To
build the query I do something like this (I have simplified this here,
because my entity model and my code is a lot more complex, but my error
of understanding should be enclosed in this example):
PathBuilder<Root> rootPath = new PathBuilder<Root>(Root.class, "root", validator);
PathBuilder<InnerRoot> innerRootPath = rootPath.get("innerRoots", InnerRoot.class);
PathBuilder<RootChild> rootChildPath = rootPath.get("childs", RootChild.class);
PathBuilder<InnerRootChild> innerRootChildPath = innerRootPath.get("childs", InnerRootChild.class);
BooleanBuilder booleanBuilder = new BooleanBuilder();
StringPath stringPath1 = rootChildPath.getString("someProperty");
booleanBuilder.and(stringPath1.containsIgnoreCase("test1"));
StringPath stringPath2 = rootChildPath.getString("someOtherProperty");
booleanBuilder.and(stringPath2.containsIgnoreCase("test2));
JPQLQuery<Long> query = JPAExpressions.select(Expressions.path(Long.class, rootPath, "id")).from(rootPath);
query.innerJoin(innerRootPath);
query.innerJoin(rootChildPath);
query.innerJoin(innerRootChildPath);
query.where(builder);
The problem seems to be the joining. How can I join and set the correct alias?
Here is my simplified object model:
@Entity
public class Root {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "root", cascade = CascadeType.ALL, orphanRemoval = true)
private SortedSet<Child> childs = new TreeSet<Child>();
@OneToMany(fetch = FetchType.EAGER, mappedBy = "root", cascade = CascadeType.ALL, orphanRemoval = true)
private SortedSet<InnerRoot> innerRoots = new TreeSet<InnerRoot>();
}
@Entity
public class InnerRoot {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "innerRoot", cascade = CascadeType.ALL, orphanRemoval = true)
private SortedSet<Child> childs = new TreeSet<Child>();
}
@Entity
@DiscriminatorColumn(name = "CONTEXT", discriminatorType = DiscriminatorType.STRING)
public abstract class Child {
... some properties
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("RootChild")
public class RootChild {
@ManyToOne(fetch = FetchType.LAZY)
private Root root;
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("InnerRootChild")
public class InnerRootChild {
@ManyToOne(fetch = FetchType.LAZY)
private InnerRoot innerRoot;
}
Cheers Maarten