Я пытаюсь написать запрос (используя JPQL), чтобы получить все теги и как часто каждый из них ссылается на все элементы. JPQL является:JPQL left external join on many to many отношения
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) будет равен нулю).
Однако, когда этот запрос выполняется, он возвращает только теги, у которых есть связанные с ним элементы, игнорируя теги, на которые не ссылаются какие-либо элементы. Сгенерированный SQL из JPA является:
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;
Он не выполняет левое внешнее соединение, которое требуется, чтобы получить результаты, я хочу. Если бы я писал это в 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
Чтобы предоставить более подробную информацию ... У меня есть три таблицы SQL: item, tag и item_tag_map. А вот фрагмент кода из смежных классов Java:
@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;
...
Спасибо! Я пробовал это, и это работает. Сгенерированный SQL из JPQL не самый большой, но этого достаточно. –