I have the following entities
Book {
private String title;
@ManyToMany
@JoinTable(
name = "book_should_read_user",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> shouldRead; // the users who should read the book
@OneToMany(mappedBy = "book")
private Set<BookReadAction> actions; // all the read actions performed on the book
}
BookReadAction {
@ManyToOne
private Book book;
@ManyToOne
private User user;
}
Now I want to query all books that have been read by all the users in the should read collection. The following sql query in postgres does the trick :
select *
from book
where id in (
select distinct id
from (
select book.id id,
array_agg(book_should_read_user.user_id) suggested_readers,
array_agg(distinct book_read_action.user_id) read_by
from book b
inner join book_should_read_user on book.id = book_should_read_user.book_id
inner join book_read_action on book.id = book_read_action.book_id
group by book.id) subquery
where suggested_readers <@ read_by)
I however want to add this clause programmatically so i'd rather use JPA criteria API. Despite some attempts i struggled. Is it possible to build a Predicate from this query in JPA criteria API?