假设我有以下两个班级;用户和位置。我想创建一个DetachedCriteria来查询用户表,并返回所有没有名称为“xyz”的位置的用户。
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
@CollectionOfElements
Set<Location> locations;
}
@Entity
public class Location{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
@Column
String name;
}
以下代码将返回所有位置名为“xyz”的用户:
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
dc.createCriteria("locations")
dc.add(Restrictions.eq("name", "xyz"));
如果我更改为Restrictions.ne(),则不起作用,因为它只会返回实际设置了位置的用户。此外,如果为用户设置了一堆位置,它将一遍又一遍地复制该用户。
有什么想法吗?
答案 0 :(得分:1)
使用原始帖子中描述的实体用户和位置:
1)检查关联的位置是否为空。
Junction or = Restrictions.disjunction();
or.add(Restrictions.isEmpty("locations"));
2)使用 LEFT_JOIN 创建位置的关联条件,并在“ ne ”限制中使用别名。 LEFT_JOIN是必需的,因此即使位置关系为空,我们仍会返回用户记录。
userCriteria.createCriteria("locations", "loc", Criteria.LEFT_JOIN);
or.add(Restrictions.ne("loc.name", "xyz"));
3)将析取添加到原始的用户条件。
userCriteria.add(or);
答案 1 :(得分:0)
您可能需要使用Restrictions.and()
,Restrictions.not()
,Restrictions.or()
和Restrictions.in()
的某种组合来使您的逆逻辑正常工作。检查http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Restrictions.html - 肯定可以完成!
为确保您只获得最多一个User
,请使用Distinct
投影(http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/标准/ Distinct.html)通过Projections.distinct()
工厂方法(http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Projections.html) - 即:
dc.setProjection(Projections.distinct(Projections.property("id")));
这样的事情应该做你需要的。