@Formula для подсчета объекта из ассоциации @OneToMany в весенних данных jpa - PullRequest
1 голос
/ 21 ноября 2019

В java rest api, с весенней загрузкой и spring-dta-jpa, db is postgresql У меня есть Book сущность, которая содержит bookCopies. Эти bookCopies могут быть доступны или нет. Я пытаюсь найти книгу с количеством доступных копий. Книги можно искать по названию или имени автора.

Мне удается получить информацию, добавив поле @Transient в мою сущность книги, с аннотацией @Transient для метода getNbCopiesAvailable(), но меня просят сделать это с аннотацией @Formulaи я не могу понять, как это сделать.

На самом деле я получаю сообщение об ошибке:

org.postgresql.util.PSQLException: ERREUR: plus d'une ligne renvoyée par une sous-requête utilisée comme une expression 
// which means that several lines are sent by the sub-query

Вот мои сущности:

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

    @NotNull
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "book_author",
               joinColumns = @JoinColumn(name = "book_id"),
               inverseJoinColumns = @JoinColumn(name = "author_id"))
    private Set<Author> authors = new HashSet<>();

    @Formula("(SELECT COUNT(bc.id) FROM book b left join book_copy bc on bc.book_id = b.id  WHERE bc.available = 'true' GROUP BY b.id)")
    private Long nbCopiesAvailable;


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

Вот мой репозиторий с запросом на получение книг по названию и автору:

    @Query("select b, a from Book b join b.authors a where b.title like %:title% and concat(a.firstName, ' ', a.lastName) like %:author%")
    List<Book> findByTitleAndAuthor(@Param("title")String title,@Param("author") String author);

@Formula("(SELECT COUNT(bc.id) FROM book b left join book_copy bc on bc.book_id = b.id WHERE bc.available = 'true' GROUP BY b.id)") было трудно писать без синтаксических ошибок, и мне странно смешивать нативный sql и jpql. Но если я попытаюсь написать @Formula в jpql, он не будет работать вообще.

Я проверил эту тему, которая была наиболее близкой к моей проблеме ( @ Счетчик формул для ManyToMany ), но это все еще не работает.

...