开发者社区> 问答> 正文

具有单向关系的条件API

我有三个实体。我需要构造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类的会话我该怎么办?

展开
收起
小六码奴 2019-10-09 19:05:31 1007 0
1 条回答
写回答
取消 提交回答
  • Root subRoot = sub.from(Client.class); Join<Session, Client> sessionClientJoin = subRoot.join("client"); 此联接显示为“联接到绑定到客户机属性的客户机类实体”。 Client没有属性client-这就是错误的意思。

    也许你想加入与客户的对话

    Join<Client, Session> sessionClientJoin = subRoot.join("sessions"); 我的建议是开始使用静态基因模型。这将保证属性的有效性和编译时的类型安全性。

    2019-10-09 19:06:48
    赞同 展开评论 打赏
问答分类:
API
问答地址:
问答排行榜
最热
最新

相关电子书

更多
数据资源的基础设施API总线 立即下载
API 网关实践 立即下载
API平台的安全实践 立即下载