2013-12-10 1 views
1

Я пытаюсь написать запрос (используя 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; 
... 

ответ

4

Я не уверен, если это ошибка 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 
+0

Спасибо! Я пробовал это, и это работает. Сгенерированный SQL из JPQL не самый большой, но этого достаточно. –

Смежные вопросы