我有三个实体。我需要构造Criteria API,如果唯一用户将超过userCount变量,则可以选择项目。
@Entity @Table(name = "client") public class Client { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Getter @Setter private Long id; }
@Entity @Table(name = "session") public class Session { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Getter @Setter private Long id;
@ManyToOne
@JoinColumn(name = "client_id", referencedColumnName = "id")
@Getter @Setter private Client client;
@ManyToOne
@JoinColumn(name = "project_id", referencedColumnName = "id")
@Getter @Setter private Project project;
}
@Entity @Table(name = "project") public class Project { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Getter @Setter private Long id; } 我要选择所有项目,其中唯一用户> = userCount。我在jpql中构造查询
@Query("select p from Project p where (select distinct count(cli.id) from Client as cli join Session sess on sess.client = cli join Project as proj on proj = sess.project where proj.id = p.id) >= :userCount") 我写了标准:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Project> cq = cb.createQuery(Project.class);
Root<Project> projectRoot = cq.from(Project.class);
List<Predicate> predicates = new ArrayList<>();
Subquery<Long> sub = cq.subquery(Long.class);
Root<Client> subRoot = sub.from(Client.class);
Join<Client, Session> sessionClientJoin = subRoot.join("sessions");
Join<Session, Project> sessionProjectJoin = sessionClientJoin.join("project");
sub.select(cb.count(subRoot.get("id"))).distinct(true);
sub.where(cb.equal(projectRoot.get("id"), sessionProjectJoin.get("id")));
predicates.add(cb.greaterThanOrEqualTo(sub, DefaultParamsHolder.NUMBER_OF_USERS));
cq.select(projectRoot);
cq.where(predicates.toArray(new Predicate[0]));
List<Project> project = em.createQuery(cq).getResultList();
这项工作正常,但是此条件要求在Client类中进行会话。
@Entity @Table(name = "client") public class Client { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Getter @Setter private Long id;
@OneToMany(mappedBy = "client", fetch = FetchType.LAZY)
private List<Session> sessions;
} 这对我不好。我需要在Client类中没有会话的情况下构造Criteria API。我尝试了这个:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Project> cq = cb.createQuery(Project.class);
Root<Project> projectRoot = cq.from(Project.class);
List<Predicate> predicates = new ArrayList<>();
Subquery<Long> sub = cq.subquery(Long.class);
Root<Client> subRoot = sub.from(Client.class);
Join<Session, Client> sessionClientJoin = subRoot.join("client");
Join<Session, Project> sessionProjectJoin = sessionClientJoin.join("project");
sub.select(cb.count(subRoot.get("id"))).distinct(true);
sub.where(cb.equal(projectRoot.get("id"), sessionProjectJoin.get("id")));
predicates.add(cb.greaterThanOrEqualTo(sub, DefaultParamsHolder.NUMBER_OF_USERS));
cq.select(projectRoot);
cq.where(predicates.toArray(new Predicate[0]));
List<Project> project = em.createQuery(cq).getResultList();
这行不通。
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [client] on this ManagedType [com.engage.domain.model.statisctic.Client] 没有Client类的会话我该怎么办?
Root subRoot = sub.from(Client.class); Join<Session, Client> sessionClientJoin = subRoot.join("client"); 此联接显示为“联接到绑定到客户机属性的客户机类实体”。 Client没有属性client-这就是错误的意思。
也许你想加入与客户的对话
Join<Client, Session> sessionClientJoin = subRoot.join("sessions"); 我的建议是开始使用静态基因模型。这将保证属性的有效性和编译时的类型安全性。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。