将条件 API + JPA 规范与 IN 表达式和 Spring 引导一起使用

Using Criteria API + JPA Specifications with IN Expression and Spring Boot

我在 Kotlin 中实现了 https://www.baeldung.com/spring-data-criteria-queries#specifications 中的示例。为此,我扩展了接口存储库:

interface BookRepository : JpaRepository<Book, String>, JpaSpecificationExecutor<Book>

并在 Kotlin 中创建了两个方法以创建规范实例:

fun hasAuthor(author: String?): Specification<Book?>? {
    return Specification<Book?> { book, cq, cb -> cb.equal(book.get<Any>("author"), author) }
}

fun titleContains(title: String): Specification<Book?>? {
    return Specification<Book?> { book, cq, cb: CriteriaBuilder -> cb.like(book.get("title"), "%$title%") }
}

现在,当作者和标题只是一个字符串时,我可以按预期简单地执行此操作:

fun getFilteredBooks(parameters: BookFilterParameters): List<Books> {

    return bookRepository.findAll(where(hasAuthor(parameters.bookName)).and(hasTitle(parameters.title)))
}

现在考虑 author 不仅仅是一个字符串,而是一个实体:

@Entity
@Table(
    name = "book",
    schema = "book"
)
data class Book(
    @Id
    var id: String,    

    @ManyToOne(cascade = [CascadeType.DETACH, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE])
    @JoinColumn(name="author")
    var author: Author? = null,

    @Column
    var title: String? = null
)
...

此外,我想像这样比较整个作者列表:

fun hasAuthors(authorsFirstName: List<String>): Specification<Book?>? {
    return Specification<Book?> { book, cq, cb -> cb.`in`(book.get<Any>("author.firstName")).value(authorsFirstName) }
}

但是,这会导致出现以下错误消息:

Unable to locate Attribute  with the the given name [author.firstName] on this ManagedType [de.bookstore.Book]

如何正确定义请求?

尝试

fun hasAuthors(authorsFirstName: List<String>): Specification<Book?>? {
    return Specification<Book?> {
        book, cq, cb -> cb.in(book
            .join<Book, Author>("book")
            .get<Any>("firstName")).value(authorsFirstName)
    }
}