2
我有两个独立的实体类:Job和JobOrgUnitCfg 下面我把两段代码做成同样的选择对象。where语句的区别beetwen JPQL和CriteriaBuilder
在JPQL首先查询:
Query jobOrgUnitCfgQuery = entityManager.createQuery(
"SELECT c FROM JobOrgUnitCfg c WHERE c.orgId = :orgId and c.schedulerNextActivation < current_timestamp and c.active = :active and " +
" not exists (SELECT j FROM Job j WHERE j.orderId = c.orderId and j.orgId = c.orgId and j.status <> :jobStatus)");
jobOrgUnitCfgQuery.setParameter("orgId", orgId);
jobOrgUnitCfgQuery.setParameter("jobStatus", JobStatusEnum.End);
jobOrgUnitCfgQuery.setParameter("active", Boolean.TRUE);
return jobOrgUnitCfgQuery.getResultList();
和第二查询建立与CriteriaBuilder:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<JobOrgUnitCfg> criteria = cb.createQuery(JobOrgUnitCfg.class);
Root<JobOrgUnitCfg> jobOrgUnitCfgRoot = criteria.from(JobOrgUnitCfg.class);
Subquery<Job> subquery = criteria.subquery(Job.class);
Root<Job> jobRoot = subquery.from(Job.class);
subquery.where(
cb.and(
cb.equal(jobRoot.get(Job_.orderId), jobOrgUnitCfgRoot.get(JobOrgUnitCfg_.orderId)),
cb.equal(jobRoot.get(Job_.orgId), jobOrgUnitCfgRoot.get(JobOrgUnitCfg_.orgId)),
cb.not(cb.equal(jobRoot.get(Job_.status), JobStatusEnum.End))
)
);
Predicate where = cb.and(cb.equal(jobOrgUnitCfgRoot.get(JobOrgUnitCfg_.orgId), orgId),
cb.lessThan(jobOrgUnitCfgRoot.get(JobOrgUnitCfg_.schedulerNextActivation), cb.currentTimestamp()),
cb.equal(jobOrgUnitCfgRoot.get(JobOrgUnitCfg_.active), Boolean.TRUE),
cb.not(cb.exists(subquery))
);
criteria.where(where);
TypedQuery<JobOrgUnitCfg> query = entityManager.createQuery(criteria);
return query.getResultList();
首先产生错误的where子句(复制里面的子查询表S_JOBS_ORG_UNIT_CFG):
SELECT ... FROM S_JOBS_ORG_UNIT_CFG t0
WHERE ((((t0.ORG_ID = ?) AND (t0.SCHEDULER_NEXT_ACTIVATION < SYSDATE)) AND (t0.ACTIVE = ?))
AND NOT EXISTS (SELECT ? FROM S_JOBS_ORG_UNIT_CFG t2, S_JOBS t1 WHERE ((((t1.ORDER_ID = t2.ORDER_ID) AND (t1.ORG_ID = t2.ORG_ID)) AND (t1.STATUS <> ?)) AND (t0.ORDER_ID = t2.ORDER_ID))))
来自Criteriabuilder的sql是正确的:
SELECT ... FROM S_JOBS_ORG_UNIT_CFG t0
WHERE ((((t0.ORG_ID = ?) AND (t0.SCHEDULER_NEXT_ACTIVATION < SYSDATE)) AND (t0.ACTIVE = ?))
AND NOT EXISTS (SELECT ? FROM S_JOBS t1 WHERE (((t1.ORDER_ID = t0.ORDER_ID) AND (t1.ORG_ID = t0.ORG_ID)) AND NOT ((t1.STATUS = ?)))))
有人能解释我在我的JPQL有什么问题吗?
谢谢。我检查了最新发布的eclipselink 2.3.0版,但尚未修复。 –