gpt4 book ai didi

java - 具有单向关系的 Criteria API

转载 作者:行者123 更新时间:2023-12-01 23:28:34 25 4
gpt4 key购买 nike

我有三个实体。我需要构建 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();

这工作正常,但此标准需要客户端类中的 session 。

@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;
}

这对我来说很糟糕。我需要在客户端类中构建没有 session 的 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]

在客户端类中没有 session 的情况下如何做到这一点?

最佳答案

你有

Root<Client> subRoot = sub.from(Client.class);
Join<Session, Client> sessionClientJoin = subRoot.join("client");

此连接表示“连接到绑定(bind)到客户端属性的客户端类实体”。Client 没有属性 client - 这就是错误所说的内容。

也许您想加入客户端的 session

   Join<Client, Session> sessionClientJoin = subRoot.join("sessions");

我的建议是开始使用静态生成的元模型。这将保证编译时属性的有效性和类型安全。

https://www.baeldung.com/hibernate-criteria-queries-metamodel

关于java - 具有单向关系的 Criteria API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58299293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com