Ole*_*lov 5 sql hibernate jpa criteria-api spring-data-jpa
有一个Event
类:
@Entity
public class Event {
@Id
private Integer id;
@ManyToOne(cascade = CascadeType.ALL)
private Company company;
@Column
private Long time;
...
}
Run Code Online (Sandbox Code Playgroud)
我想要一个EventFilter
类(实现Specification
),它将CriteriaQuery
以与以下 SQL 查询相同的方式生成选择实体:
SELECT *
FROM events e1
WHERE e1.time = (
SELECT MAX(time)
FROM events e2
WHERE e1.company_id = c2.company_id
)
Run Code Online (Sandbox Code Playgroud)
筛选结果将仅包含每个公司具有唯一值Company
和最大值的事件。time
这是EventFilter
我最终得到的课程:
public class EventFilter implements Specification<Event> {
@Override
public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> q, CriteriaBuilder cb) {
Subquery<Long> subquery = q.subquery(Long.class);
Root<Event> subRoot = subquery.from(Event.class);
subquery.select(cb.max(root.get("time")))
.where(cb.equal(root.get("company"), subRoot.get("company")));
return cb.equal(root.get("time"), subquery);
}
}
Run Code Online (Sandbox Code Playgroud)
调用时EventRepository#findAll(EventFilter filter)
,结果根本不会被过滤。请帮助我正确地实现这个逻辑。
在检查 Hibernate 生成的 SQL 语句后,我发现了一个错误:root
wasused 而不是subRoot
. 正确的方法体是:
Subquery<Long> sub = q.subquery(Long.class);
Root<Event> subRoot = sub.from(Event.class);
sub.select(cb.max(subRoot.get("time")))
.where(cb.equal(root.get("company"), subRoot.get("company")));
return cb.equal(root.get("time"), sub);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3723 次 |
最近记录: |