Как объединить отдельные и отсортированные в весенних данных спецификации запроса jpa с объединениями - PullRequest
6 голосов
/ 21 февраля 2020

Пример настройки:

Сущность

@Entity
class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @ManyToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinTable(name = "book_authors",
            joinColumns = [JoinColumn(name = "book_id")],
            inverseJoinColumns = [JoinColumn(name = "author_id")])
    var authors: MutableSet<Author> = HashSet()

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "publisher_id")
    lateinit var publisher: Publisher
}

И Автор, и Издатель являются простыми сущностями, имеющими только идентификатор и имя.

Данные пружины jpa BookSpecification: (обратите внимание на отличительные при запросе)

fun hasAuthors(authorNames: Array<String>? = null): Specification<Book> {
    return Specification { root, query, builder ->
        query.distinct(true)
        val matchingAuthors = authorRepository.findAllByNameIn(authorNames)
        if (matchingAuthors.isNotEmpty()) {
            val joinSet = root.joinSet<Book, Author>("authors", JoinType.LEFT)
            builder.or(joinSet.`in`(matchingContentVersions))
        } else {
            builder.disjunction()
        }
    }
}

Выполнение запроса (с возможностью просмотра страниц с сортировкой на publisher.name)

bookRepository.findAll(
    Specification.where(bookSpecification.hasAuthors(searchRequest)),
    pageable!!)

Запрос REST:

MockMvcRequestBuilders.get("/books?authors=Jane,John&sort=publisherName,desc")

Это приводит к следующей ошибке:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Order by expression "PUBLISHERO3_.NAME" must be in the result list in this case;

Проблема в сочетание отличного и сортированного. Отличительное требует, чтобы имя издателя было в полях выбора для возможности сортировки.

Как это исправить с помощью запроса спецификации?

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

ты не можешь сделать это. в основном, если у вас есть отдельные и вы хотите сортировать, вы можете использовать только выбранные столбцы.

, что вы можете сделать, это использовать row_number() оконную функцию вместо distinct, а затем выбрать все с помощью row_number=1. Вы можете найти (немного старый) пример здесь: { ссылка }

0 голосов
/ 25 февраля 2020

Скорее всего, вам придется явно выбрать столбец PUBLISHERO3_.NAME, например, так:

query.select(builder.array(root.get("PUBLISHERO3_.NAME"), root.get("yourColumnHere")));

Объединенные столбцы, вероятно, не включены по умолчанию, поскольку они не входят в область действия root тип c.

...