@Formula 从 spring data jpa 中的 @OneToMany 关联中计数对象

Ala*_*ine 6 java spring hibernate spring-data-jpa

在 java Rest api 中,使用 spring boot 和 spring-dta-jpa,db 是 postgresql\n我有一个Book包含bookCopies. 这些图书bookCopies可以是可用的,也可以是不可用的。\n我正在尝试检索具有可用副本数量的图书。\n可以按书名或作者姓名搜索图书。

\n\n

我设法通过@Transient在我的书籍实体中添加一个字段并在方法@Transient上添加注释来获取信息getNbCopiesAvailable(),但系统要求我使用@Formula注释来完成此操作,但我不知道如何操作。

\n\n

我实际上收到一个错误:

\n\n
org.postgresql.util.PSQLException: ERREUR: plus d\'une ligne renvoy\xc3\xa9e par une sous-requ\xc3\xaate utilis\xc3\xa9e comme une expression \n// which means that several lines are sent by the sub-query\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的实体:

\n\n
org.postgresql.util.PSQLException: ERREUR: plus d\'une ligne renvoy\xc3\xa9e par une sous-requ\xc3\xaate utilis\xc3\xa9e comme une expression \n// which means that several lines are sent by the sub-query\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的存储库,其中包含按标题和作者检索书籍的查询:

\n\n
@Entity\n@Getter\n@Setter\n@NoArgsConstructor\npublic class Book {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String isbn;\n    @NotNull\n    private String title;\n\n    @JsonIgnore\n    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)\n    private List<BookCopy> copyList = new ArrayList<>();\n\n    @NotNull\n    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})\n    @JoinTable(name = "book_author",\n               joinColumns = @JoinColumn(name = "book_id"),\n               inverseJoinColumns = @JoinColumn(name = "author_id"))\n    private Set<Author> authors = new HashSet<>();\n\n    @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)")\n    private Long nbCopiesAvailable;\n\n\n@Entity\n@Getter\n@Setter\n@Builder\n@AllArgsConstructor\npublic class BookCopy {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String barcode;\n    private String editor;\n    private boolean available = true;\n\n    @ManyToOne(fetch = FetchType.LAZY)\n    private Book book;\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n @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)")\n很难在没有语法错误的情况下编写,并且混合本机 sql 和 jpql 对我来说很奇怪。但如果我尝试@Formula在 jpql 中编写它,它根本不起作用。

\n\n

我检查了这个与我的问题最接近的主题(@Formula count on ManyToMany),但它仍然不起作用。

\n

Sim*_*lli 5

您需要在 where 子句中引用该书:

@Formula("(SELECT COUNT(bc.id) FROM book b " +
         "left join book_copy bc on bc.book_id = b.id " +
         "WHERE bc.available = 'true' " +
         "and b.id = id " + // This is the important condititon
         "GROUP BY b.id)")
private Long nbCopiesAvailable;
Run Code Online (Sandbox Code Playgroud)

否则您的查询将返回所有书籍。