给出了使用Hibernate映射到Java对象的RDBMS中的以下域模型。
┌─────────┐ ┌─────────────┐
│ Project │ 1 0..n │ UserSetting │
├─────────┼------------┼─────────────┤
│ name │ │ username │
└─────────┘ │ favorite │
└─────────────┘用户可以将项目标记为受欢迎的项目,该项目由相关(可选) UserSetting条目反映。如果用户没有标记项目,数据库中就会出现 no entry,这意味着项目不是最喜欢的。想象一下UserSetting是“稀疏”的。
此外,给出:实体应该通过JPA获取,Hibernate作为提供者。
假设Project和UserSetting表可以非常大。优化数据库架构不应受此问题影响。假设存在有效的索引。
对于给定的用户,我希望高效地获取所有项目,包括该特定用户最喜欢的状态。注意分类标准!
我最初的方法是制定以下JPQL查询:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
WHERE us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC如果currentUser确实有,而不是有UserSetting,但是userB有,这是行不通的。UserSetting of userB将被加入,但由于WHERE子句的原因,项目不会被列出。
幸运的是,JPA2.1引入JOINS子句 (Javadoc )可以用于将查询重新表示为:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
ON us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC不幸的是,Hibernate (4.3.6)不支持使用"ON子句“(Hibernate的lingus中的”with子句“)进行fetch连接,并且除以下情况外退出:
org.hibernate.hql.internal.ast.QuerySyntaxException: with-clause not allowed on fetched associations; use filters如何重新构造查询以实现功能并满足我的约束:
发布于 2014-08-08 19:22:32
最近的发现是,JPA 2.1 (JSR 338)规范定义了语法,而不允许使用"ON子句“来获取联接。
我的解决方法是省略Hibernate的对象映射特性,并显式地选择Project和UserSetting所需的字段。
发布于 2015-06-24 12:34:13
您也可以使用以下方法检索不需要UserSettings的项目:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
WHERE us is null OR us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC这个
us is null查询的WHERE子句中的一部分起了作用。
https://stackoverflow.com/questions/25004892
复制相似问题