【发布时间】:2011-05-10 09:32:49
【问题描述】:
我有以下表格
CREATE TABLE "COMPANIES" (
"ID" NUMBER NOT NULL ,
"NAME" VARCHAR2 (100) NOT NULL UNIQUE
)
/
CREATE TABLE "COMPANIESROLES" (
"ID" NUMBER NOT NULL ,
"COMPANYID" NUMBER NOT NULL ,
"ROLENAME" VARCHAR2 (30) NOT NULL
)
/
CREATE TABLE "ROLES" (
"NAME" VARCHAR2 (30) NOT NULL
)
/
此结构代表许多公司以及每个公司允许的角色。对于这些表,都有对应的 Hibernate 对象:
public class Company implements Serializable {
private Long id;
private String name;
private Set<Role> companyRoles;
//(getters and setters omitted for readability)
}
public class Role implements Serializable {
private String name;
//(getters and setters omitted for readability)
}
使用 Hibernate Criteria API 找出所有具有特定角色的公司是没有问题的:
Session session = this.sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Company.class);
criterion = Restrictions.eq("companyRoles.name", "ADMIN");
criteria.add(criterion);
List<Company> companyList = criteria.list();
Hibernate 将其转换为 SQL 查询(大约)
SELECT *
FROM companies this_
inner join companyroles cr2_
ON this_.id = cr2_.companyid
inner join roles role1_
ON cr2_.rolename = role1_.NAME
WHERE role1_.NAME = 'ADMIN'
现在的问题是:如何反转查询,即找出所有没有“ADMIN”角色映射的公司?如果我只是尝试通过设置来反转标准
criterion = Restrictions.ne("companyRoles.name", "ADMIN");
(不等于而不是等于),Hibernate 创建这样的查询
SELECT *
FROM companies this_
inner join companyroles cr2_
ON this_.id = cr2_.companyid
inner join roles role1_
ON cr2_.rolename = role1_.NAME
WHERE role1_.NAME != 'ADMIN'
显然,这不会产生所需的输出,因为列表仍然包含具有“ADMIN”角色的公司,只要这些公司至少有一个其他角色。
我想要的是一个没有“管理员”角色的公司列表。作为一个额外的限制,如果可能的话,这应该可以通过修改 Criterion 对象来实现(这是因为标准是作为内部框架的一部分自动构建的,并且不可能在那里进行更大的更改)。 当 Criteria 对象包含其他附加条件时,该解决方案也应该有效。
这是怎么做到的,或者是吗?
【问题讨论】: