Model:
@Entity
public class User {
@Id
private Integer id;
@JoinColumn(name = "user_id")
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Project> projects;
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "Type")
public abstract class Project {
@Id
private Integer id;
private String name;
}
@Entity
@DiscriminatorValue("Administrative")
public class AdminProject extends Project {
private String departmentName;
}
@Entity
@DiscriminatorValue("Design")
public class DesignProject extends Project {
private String companyName;
}
I am trying to use JPA's criteria api to query for User
entities based on an attribute of an implementation of Project
. For example, query all users that have a project with "SOME_NAME" department (that field does not exist on DesignProject
).
I see there is a way of doing so via downcasting of the Project
entity for the query. I am trying something similar to:
CriteriaBuilder cb...
Root<User> userRoot...
root = ((From) root).join("projects", JoinType.LEFT);
root = cb.treat(root, AdminProject.class);
root = root.get("departmentName");
Exception:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias2.departmentName' [select generatedAlias0 from io.github.perplexhub.rsql.model.User as generatedAlias0 left join generatedAlias0.projects as generatedAlias1 where treat(generatedAlias2 as io.github.perplexhub.rsql.model.AdminProject).departmentName=:param0]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias2.departmentName' [select generatedAlias0 from io.github.perplexhub.rsql.model.User as generatedAlias0 left join generatedAlias0.projects as generatedAlias1 where treat(generatedAlias2 as io.github.perplexhub.rsql.model.AdminProject).departmentName=:param0]
What am I missing? Is it something related to the join, or how the downcasting occurs afterwards?
Edit
After the answer by @K.Nicholas, I have managed to make the query work on an isolated scenario, but not on my app.
But, I noticed that the entityManager.createQuery(query)
call throws the exception above when called for the first time, and it works if I call it again without changing the query object. Here is the query generated on the second call (this query finds the objects I want from the database):
select generatedAlias0 from User as generatedAlias0 left join generatedAlias0.projects as generatedAlias2 where treat(generatedAlias2 as io.github.perplexhub.rsql.model.AdminProject).departmentName=:param0
Why is the entity manager creating two different queries when called two consecutive times?