我有一个Employee模型,它有一个Manager字段,可以为null,或者指向另一个Employee。
我试图运行一个查询,该查询将撤回位于层次结构中某个Manager下方的Employees列表。所以我从以下WHERE子句开始:
(e.Manager.Id = :managerId or
(e.Manager is not null and e.Manager.Manager.Id = :managerId))
这似乎工作正常,返回员工的经理是指定的经理,或者经理是由指定的经理管理的。
我尝试将它提升到一个新的水平:
(e.Manager.Id = :managerId or
(e.Manager is not null and e.Manager.Manager.Id = :managerId) or
(e.Manager.Manager is not null and e.Manager.Manager.Manager.Id = :managerId))
然后,只返回指定经理管理的经理的员工。由指定经理管理的员工不会被退回。
这怎么可能?当然,如果条款的第一部分是匹配的(由指定的经理管理),那么该条款的其余部分是否应该不被评估?
答案 0 :(得分:1)
如果您没有比您在问题中提到的更多级别的管理,那么此SQL语句应该有效。
select e1.* from Employee e1
left join Employee manager on e1.manager = manager.id
left join Employee bigManager on manager.manager = bigManager.id
where e1.manager = 3 or manager.manager = 3 or bigManager.manager = 3
3只是我在db中测试时使用的管理器的ID
答案 1 :(得分:1)
如果没有明确的JOIN,有时Hibernate会丢失并且无法生成开发人员认为应该生成的查询。
所以,一个好的做法总是明确你的JOIN(正如@Badzen所建议的那样)。
我无法测试查询,但请尝试:
Select e FROM Employee e
LEFT JOIN e.manager m1
LEFT JOIN m1.manager m2
LEFT JOIN m2.manager m3
WHERE m1.id = :managerId
or (m1 IS NOT NULL and m2.id = :managerId)
or (m2 IS NOT NULL and m3.id = :managerId)
通过这种方式,生成的查询是可预测的,并且更容易理解问题在哪里。