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

时间:2012-05-11 10:14:32

标签: java hibernate hibernate-criteria

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

Criteria criteria = db.getSession().createCriteria(Vendor.class);
criteria.add(Restrictions.isEmpty("models"));

当使用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)

我想要做的是在“不存在”部分中添加限制,以便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 )

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

1 个答案:

答案 0 :(得分: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));

相当于以下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)