Сложный критерий JPA «многие ко многим» - PullRequest
2 голосов
/ 25 августа 2011

У меня есть две сущности, Ablum и Image, которые во многих отношениях. Я хочу сделать критерий запроса, чтобы получить все альбомы и рассчитывать, сколько изображений у них есть. Я не хочу сначала получить все альбомы, а затем зациклить результат, чтобы получить количество, так как было бы очень много запросов sql. Я работал 2 ночи и полностью потерян. Если не могу найти выход, может быть, мне нужно отступить, чтобы использовать SQL.

Ответы [ 2 ]

3 голосов
/ 26 августа 2011

Благодаря вдохновению digitaljoel я обнаружил, что у CriteriaBuilder есть вызов метода «size», который можно поместить в коллекции. Ниже приведен код:

    CriteriaBuilder cb = getCriteriaBuilder();
    CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
    Root<AlbumEntity> albums = query.from(AlbumEntity.class);
    query.select(cb.array(albums.get(AlbumEntity_.id), cb.size(albums.get(AlbumEntity_.images))));
    query.groupBy(albums.get(AlbumEntity_.id));

Здесь вызов groupBy является обязательным, в противном случае произойдет ошибка. Но этот метод предназначен для загрузки идентификаторов AlbumEntity, а не самой сущности. Сущность Album может быть загружена, если используется код ниже:

    query.select(cb.array(albums, cb.size(albums.get(AlbumEntity_.images))));
    query.groupBy(albums.get(AlbumEntity_.id), ...);

groupBy должен включать все свойства сущности альбома. И все равно не работает, если у сущности альбома есть свойство типа blob.

2 голосов
/ 25 августа 2011

Я собираюсь сделать некоторые предположения, поскольку вы не опубликовали свое сопоставление JPA, поэтому я предполагаю, что у каждого альбома есть List<YourImageClass> images для сопоставления многих ко многим.С этим, что-то вроде этого будет работать.

select a, size(a.images) from Album a

Это вернет List<Object[]>, где List.get(i)[0] будет альбом, а List.get(i)[1] будет соответствующий размер коллекции изображений.

В качестве альтернативы, вы можете определить простой бин для выбора.Что-то вроде

public class AlbumResult {
    private Album album;
    private Integer imageCount;
    public AlbumResult( Album a, Integer size ) {
        album = a;
        imageCount = size;
    }
    // getters and setters here
}

Тогда вы могли бы сделать

select new AlbumResult(a, size(a.images)) from Album a;

Я никогда не имел дело с критериями запросов, но JPQL достаточно прост, его должно быть тривиально, чтобы перевести его в запрос критериев.

...