型号:
@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;
}
我正在尝试使用jpa的criteriaapi来查询 User
基于实现的属性的实体 Project
. 例如,查询具有“some\ u name”department(该字段在上不存在)项目的所有用户 DesignProject
).
我看到有一种方法可以通过对 Project
查询的实体。我正在尝试类似的方法:
CriteriaBuilder cb...
Root<User> userRoot...
root = ((From) root).join("projects", JoinType.LEFT);
root = cb.treat(root, AdminProject.class);
root = root.get("departmentName");
例外情况:
org.springframework.dao.invaliddataaccessapiusageexception:org.hibernate.hql.internal.ast.querysyntaxexception:无效路径:“generatedalias2.departmentname”[从io.github.influsehub.rsql.model.user中选择generatedalias0作为generatedalias0左连接generatedalias0.projects作为generatedalias1 where treat(generatedalias2作为io.github.hub.rsql.model.adminproject).departmentname=:param0];嵌套异常为java.lang.illegalargumentexception:org.hibernate.hql.internal.ast.querysyntaxexception:invalid path:'generatedalias2.departmentname'[从io.github.implesshub.rsql.model.user选择generatedalias0作为generatedalias0 left join generatedalias0.projects作为generatedalias1 where treat(generatedalias2作为io.github.hub.rsql.model.adminproject).departmentname=:param0]
我错过了什么?是与连接有关,还是之后的向下转换是如何发生的?
编辑
在@k.nicholas的回答之后,我设法使查询在一个单独的场景中工作,但在我的应用程序中没有。但是,我注意到 entityManager.createQuery(query)
call在第一次调用时抛出上面的异常,如果我再次调用它而不更改查询对象,它就会工作。下面是第二次调用时生成的查询(此查询从数据库中查找所需的对象):
从用户中选择generatedalias0作为generatedalias0 left join generatedalias0.projects作为generatedalias2 where treat(generatedalias2作为io.github.implessHub.rsql.model.adminproject)。部门名称=:param0
为什么实体管理器在连续调用两次时会创建两个不同的查询?
1条答案
按热度按时间d5vmydt91#
我会做的
Entitys
有点不同,你会看到的。主要的问题是你正在使用User
作为你的根,加入一个Projects
. 这是一个问题,因为您应该在Project
分类并使用projects
字段作为仅查询字段。我就是这么做的。这样效果更好。这也是一个问题,因为你必须做一个join fetch
而不是join
所以projects
把它带走users
.首先,实体是这样的:
经过一番挖掘,我发现了一个jpql查询可以实现这个功能。这是一个起点:
经过进一步的挖掘,我发现
treat
如果你做得正确的话,它工作得很好,而且对于jpa2.1你应该使用EntityGraph
一定要拿到钱join
做某事fetch
.顺便说一下,生成的查询略有不同,但我没有仔细研究它们。你应该。