Hibernate Criteria:为Restrictions.isEmpty添加额外的限制

sim*_*mon 3 java hibernate hibernate-criteria

我创建了一个Hibernate(3.5)Criteria查询:

Criteria criteria = db.getSession().createCriteria(Vendor.class);
criteria.add(Restrictions.isEmpty("models"));
Run Code Online (Sandbox Code Playgroud)

当使用Criteria.list执行时,Hibernate会生成以下SQL(为了便于阅读而简化):

SELECT this_.*
FROM   VENDOR this_
       left outer join MODEL models1_
         ON this_.id = models1_.VENDOR_ID
WHERE  NOT EXISTS (SELECT 1
                   FROM   MODEL
                   WHERE  this_.id = VENDOR_ID)
Run Code Online (Sandbox Code Playgroud)

我想要做的是在"不存在"部分中添加一个限制,以便SQL查询看起来像这样

SELECT this_.* FROM VENDOR this_
left outer join MODEL models1_
         ON this_.id = models1_.VENDOR_ID
WHERE
NOT EXISTS (SELECT 1
                             FROM   MODEL
                             WHERE  this_.id = VENDOR_ID AND DEPRECATED = 0 )
Run Code Online (Sandbox Code Playgroud)

是否可以使用Hibernate Criteria API,如果可以,怎么做?或者是否有其他可能实现相同的结果(但仍然使用Criteria API)?

JB *_*zet 14

是的,可以使用子查询:

Criteria criteria = db.getSession().createCriteria(Vendor.class, "vendor");

DetachedCriteria dc = DetachedCriteria.forClass(Vendor.class, "vendor2");
dc.createAlias("vendor2.models", "model");
dc.add(Restrictions.eq("model.deprecated", 0));
dc.add(Restrictions.eqProperty("vendor2.id", "vendor.id"));
dc.setProjection(Projections.id());

criteria.add(Subqueries.notExists(dc));
Run Code Online (Sandbox Code Playgroud)

这相当于以下HQL查询:

select vendor from Vendor vendor
where not exists(select vendor2.id from Vendor vendor2
                 inner join vendor2.models model
                 where model.deprecated = 0
                 and vendor2.id = vendor.id)
Run Code Online (Sandbox Code Playgroud)