如何解决如何使用 JPA Criteria Queries 和 Spring Data Specification 将子查询链接到主查询?
我有这三个实体:
@Entity
@Table(name="documento")
public class Documento extends AbstractAuditableActivationEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id_documento",unique=true,nullable=false)
private Long id;
...
...
@OnetoMany(fetch=FetchType.LAZY,orphanRemoval=true,cascade=CascadeType.ALL,mappedBy="documento")
private List<DocumentoEvent> events;
...
...
}
@Entity
@Table(name = "documento_event")
public class DocumentoEvent extends AbstractBpmnEvent {
private static final long serialVersionUID = 1177989257158109761L;
@Id
@Getter
@Setter
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_documento_event",nullable=false)
private Long id;
@Getter
@Setter
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id_documento",nullable = false)
private Documento documento;
}
和
@MappedSuperclass
public abstract class AbstractBpmnEvent implements Serializable {
private static final long serialVersionUID = 6718273240496032533L;
...
...
@Column(name = "bpm_task_end_time")
@Temporal(TemporalType.TIMESTAMP)
private Date bpmtaskEndTime;
@Column(name = "bpm_task_status",length = FieldsLength.EVENT_TYPE)
private String bpmtaskStatus;
...
...
}
我想要的是动态构建这样的查询:
SELECT d.id_documento
FROM documento d join documento_event de on d.id_documento = de.id_documento
WHERE de.bpm_task_status = ? AND de.bpm_task_end_time is not null AND de.bpm_task_end_time = (
SELECT max(bpm_task_end_time)
FROM documento_event de2
WHERE de2.id_documento = d.id_documento
)
使用 JPA 标准查询和 Spring 规范。 这就是我想要做的:
private List<Predicate> getPredicateRegistrodocumento(
final DocumentoFilters filters,final Root<Documento> documento,final CriteriaBuilder cb,final CriteriaQuery<?> query) {
List<Predicate> predicates = new ArrayList<Predicate>();
...
...
if(CollectionUtils.isNotEmpty(filters.getWorkflowStatusCodes())) {
predicates.add(
cb.and(
documento.join(Documento_.EVENTS).get(AbstractBpmnEvent_.BPM_TASK_STATUS).in(filters.getWorkflowStatusCodes()),cb.isNotNull(documento.join(Documento_.EVENTS).get(AbstractBpmnEvent_.BPM_TASK_END_TIME))
cb.equal(documento.join(Documento_.EVENTS).get(AbstractBpmnEvent_.BPM_TASK_END_TIME),latestEvent(query,cb,documento))
)
);
}
...
...
return predicates;
}
private Subquery<Date> latestEvent(final CriteriaQuery<?> query,final CriteriaBuilder cb){
Subquery<Date> subquery = query.subquery(Date.class);
Root<DocumentoEvent> documentoEvent = subquery.from(DocumentoEvent.class);
subquery.select(cb.greatest(documentoEvent.get(DocumentoEvent_.BPM_TASK_END_TIME))
);
return subquery;
}
我觉得我已经很接近了,但还没有完全到位,因为该子查询的作用是获取所有 MAX(bpm_task_end_time)
中的 documento_event
,而不仅仅是 documento_event.id_documento
等于 { 的行的 documento.id_documento
{1}} 的主查询。
我该怎么做?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。