【问题标题】:Using Criteria API + JPA Specifications with IN Expression and Spring Boot将 Criteria API + JPA 规范与 IN 表达式和 Spring Boot 结合使用
【发布时间】:2021-01-05 20:39:46
【问题描述】:

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

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

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

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]

如何正确定义请求?

【问题讨论】:

  • 使用javax.persistence 库中的Join 类,您可以使用相同的Specification 搜索类中的嵌套对象。见stackoverflow.com/q/42465419

标签: spring kotlin spring-data-jpa criteria-api


【解决方案1】:

试试

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)
    }
}

【讨论】:

    猜你喜欢
    • 2012-05-30
    • 2015-04-04
    • 2019-02-16
    • 1970-01-01
    • 2019-11-18
    • 2013-09-08
    • 2019-11-10
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多