I work on a rest library project with Spring boot and spring data. I have an entity Book that has a collection of BookCopies.
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String isbn;
@NotNull
private String title;
@JsonIgnore
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
private List<BookCopy> copyList = new ArrayList<>();
...
@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
public class BookCopy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String barcode;
private String editor;
private boolean available = true;
@ManyToOne(fetch = FetchType.LAZY)
private Book book;
...
And I would like to perform a request that gives me all the books and the number of copies that are available. I have no problem to perform it in standard sql:
select book.*, count(book_copy.id) as nb_copies from book
inner join book_copy on book.id = book_copy.book_id
where book.title like '%:title%'
and book_copy.available = true
group by book.id
But I can't manage to make it work in my project. I thought I could do it with jpql, but when I try to join the entity bookCopy, intellij doesn't make any autocompletion, which makes me suspect that there is a configuration problem. If I try "run query in console" it tells me "no runner found", even if I set up the database in intellij. I also tried to do it with native query, but it doesn't work either.
I managed to get a result but I think with a wrong method:
@Override
public List<Book> findByTitle(String title) {
List<Book> bookList = bookRepository.findByTitleLike("%"+title+"%");
for(Book book:bookList){
book.setCopyList(bookCopyRepository.findAllInBookWhereAvailable(book.getId(), true));
}
return bookList;
}
Which will start a query for each book to get the copylist. So I'm out of ideas and I can't get much clear infos about it. Thanks!
The following JPQL should return the same data set as your native SQL query:
select b, count(c) from Book b
join b.copyList c
where b.title like :title and c.available
group by b
Java code:
String title = ...;
final List result = em.createQuery("select b, count(c) from Book b" +
" join b.copyList c " +
" where b.title like :title and c.available " +
" group by b ")
.setParameter("title", title)
.getResultList();
for (Object res : result) {
Object[] row = (Object[]) res;
System.out.println("Book: " + row[0]);
System.out.println("BookCopy CNT: " + row[1]);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.