JPQL在多对多关系上左外连接
Posted
技术标签:
【中文标题】JPQL在多对多关系上左外连接【英文标题】:JPQL left outer join on many to many relationship 【发布时间】:2013-12-28 08:07:34 【问题描述】:我正在尝试编写一个查询(使用 JPQL)来获取所有标签以及每个标签被所有项目引用的频率。 JPQL 是:
SELECT t.id, t.name, SIZE(t.items) FROM Tag t GROUP BY t.id, t.name ORDER BY t.name ASC
请注意,有些标签没有被任何项目引用,但我仍然希望它们包含在结果中(并且期望 SIZE(t.items) 为零)。
但是,当这个查询被执行时,它只返回与它相关联的项目的标签,忽略没有被任何项目引用的标签。从 JPA 生成的 SQL 是:
SELECT t0.id as a1, t0.NAME AS a2, COUNT(t1.id) FROM tag t0, item_tag_map t2, item t1 WHERE ((t2.tag_id = t0.id) AND (t1.id = t2.item_id)) GROUP BY t0.id, t0.NAME ORDER BY t0.NAME ASC;
它没有执行获得我想要的结果所需的 LEFT OUTER JOIN。如果我用 SQL 写这个,我会做类似的事情
select t.id, t.name, count(map.item_id) from tag as t left join item_tag_map as map on map.tag_id = t.id group by t.id, t.name order by t.name ASC;
在 JPQL 中有什么方法可以做到这一点吗?我做错了什么还是JPQL的限制(或错误)?我正在使用 PostgreSQL v9.2 和 EclipseLink v2.4.2
提供更多详细信息... 我有 3 个 SQL 表:item、tag 和 item_tag_map。这里是相关Java类的sn-p:
@Entity
@Table(name="item")
public class Item implements Serializable
@Id
@Column(name="id", updatable=false)
private String id;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name = "item_tag_map",
joinColumns = @JoinColumn(name = "item_id", referencedColumnName = "id", nullable=false) ,
inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id", nullable=false) )
private List<Tag> tags;
...
@Entity
@Table(name="tag")
@NamedQueries(
@NamedQuery(name="Tag.findAllStats", query="SELECT t.id, t.name, SIZE(t.items) FROM Tag t GROUP BY t.id, t.name ORDER BY t.name ASC"),
)
public class Tag implements Serializable
@Id
@Column(name="id", updatable=false)
private long id;
private String name;
@ManyToMany(mappedBy="tags", fetch=FetchType.LAZY)
private List<Item> items;
...
【问题讨论】:
【参考方案1】:我不确定这是否是一个 EclipseLink 错误(不过对我来说似乎是一个错误),但您可能可以使用以下查询来解决问题(虽然未经测试):
select t.id, t.name, count(i.id) from Tag t
left join t.items i
group by t.id, t.name
order by t.name asc
【讨论】:
谢谢!我试过了,它有效。从 JPQL 生成的 SQL 不是最好的,但现在已经足够了。以上是关于JPQL在多对多关系上左外连接的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 6 Recipes 2nd Edition(10-9)译 -> 在多对多关系中为插入和删除使用存储过程
阶段3 1.Mybatis_09.Mybatis的多表操作_8 mybatis多对多操作-查询角色获取角色下所属用户信息