Reputation: 596
I'm looking for a way to make a join on a one-to-many relation where the many-side is defined through inheritance and the right part of the join is restricted to a specific subclass (downcast).
Say I have the entities below (example taken from here):
@Entity
public class Project {
@Id
@GeneratedValue
private long id;
private String name;
@OneToMany(cascade = CascadeType.ALL)
private List<Employee> employees;
.............
}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
@DiscriminatorColumn(name = "EMP_TYPE")
public class Employee {
@Id
@GeneratedValue
private long id;
private String name;
.............
}
@Entity
@DiscriminatorValue("F")
public class FullTimeEmployee extends Employee {
private int annualSalary;
.............
}
@Entity
@DiscriminatorValue("P")
public class PartTimeEmployee extends Employee {
private int weeklySalary;
.............
}
@Entity
@DiscriminatorValue("C")
public class ContractEmployee extends Employee {
private int hourlyRate;
.............
}
I can easily build join queries that involve properties defined in the superclass Employee
, like:
JPAQuery query = ...
QProject project = new QProject("p");
QEmployee employee = new QEmployee("e");
query.join(project.employees, employee);
query.where(employee.name.startsWith("A"));
But if I want to access a property of subclass, say FullTimeEmployee.annualSalary
, and hence restrict the join to that sub-type, how do I do that?
How do I build the the equivalent of following JPQL:
SELECT DISTINCT p FROM Project p JOIN TREAT(p.employees AS FullTimeEmployee) e WHERE e.annualSalary > 100000
Upvotes: 2
Views: 952
Reputation: 435
You can do it like this:
EntityManager em = ...;
QProject p = QProject.project;
QFullTimeEmployee e = QFullTimeEmployee.fullTimeEmployee;
List<FullTimeEmployee> emps = new JPAQuery<>(em)
.select(p)
.distinct()
.from(p)
.innerJoin(p.employees, e._super)
.where(e.annualSalary.gt(100000))
.fetch();
See also this post on the Querydsl forum: https://groups.google.com/d/msg/querydsl/4G_ea_mQJgY/JKD5lRamAQAJ
Upvotes: 3