开发者

Complex Many-to-Many JPA CriteriaQuery

开发者 https://www.devze.com 2023-03-31 06:18 出处:网络
I have two entities, Ablum and Image, which are in many to many relationship. I wanna make a criteria query that to get all Albums and the counts on how many Images they have.

I have two entities, Ablum and Image, which are in many to many relationship. I wanna make a criteria query that to get all Albums and the counts on how many Images they have. I don't want to get all 开发者_运维知识库Albums first then loop the result to get the counts as there would be so many sql requests. I've been working for 2 nights and complete lost. If cannot find a way out maybe I need to fallback to use SQL.


Thanks to digitaljoel's inspiration, I found that CriteriaBuilder has a method call "size" that can be put on collections. Below is the code:

    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));

Here the groupBy call is a must otherwise error will occur. But this method is to load the IDs of AlbumEntity, not the entity itself. The Album entity can be load if below code is used:

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

The groupBy must include all properites of the album entity. And it still does not work if the album entity has blob type property.


I'm going to have to make some assumptions since you haven't posted your JPA mapping, so I'm assuming each album has a List<YourImageClass> images for the many to many mapping. With that, something like this would work.

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

That would return a List<Object[]> where List.get(i)[0] would be the album and List.get(i)[1] would be the corresponding size of the image collection.

Alternately, you could define a simple bean to select into. Something like

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

Then you could do

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

I never deal with criteria queries, but the JPQL is simple enough it should be trivial to translate it into a criteria query.

0

精彩评论

暂无评论...
验证码 换一张
取 消