Как использовать проекционные интерфейсы с разбиением на страницы в Spring Data JPA?

Я пытаюсь получить страницу частичного объекта (NetworkSimple), используя новую функцию spring data,прогнозы

Я проверил документацию и, если я прошу только:

Collection<NetworkSimple> findAllProjectedBy();

это работает, но если я использую pageable:

Page<NetworkSimple> findAllProjectedBy(Pageable pageable);

Он выдает ошибку:

org.hibernate.jpa.criteria.expression.function.AggregationFunction$COUNT cannot be cast to org.hibernate.jpa.criteria.expression.CompoundSelectionImpl

кто-нибудь уже работал с этим ?

мой класс NetworkSimple следующий:

public interface NetworkSimple {
    Long getId();

    String getNetworkName();

    Boolean getIsActive();
}

5 ответов


Примечание: эта функция должна работать так, как описано в оригинальном плакате, но из-за эта ошибка это не так. Ошибка была исправлена для выпуска Хоппера SR2, если вы застряли на более ранней версии, то обходной путь ниже будет работать.

можно использовать Pageable С новыми функциями проекции запросов, введенными в Spring Data JPA 1.10 (Hopper). Вам нужно будет использовать @Query аннотация и вручную написать запрос для полей, которые вы require, они также должны быть сглажены с помощью AS чтобы данные Spring могли выяснить, как проектировать результаты. Есть хороший пример в spring-boot-samples часть репозитория spring boot.

в вашем примере это было бы довольно просто:

@Query("SELECT n.id AS id, n.name AS networkName, n.active AS isActive FROM Network n")
Page<NetworkSimple> findAllProjectedBy(Pageable pageable);

Я сделал предположение, что ваше лицо выглядит так:

@Entity
public class Network
{
    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @Column
    private boolean active;

    ...
}

Spring Data автоматически выведет запрос count для информации подкачки. Также можно использовать соединения в запросе для извлечения ассоциаций, а затем суммировать их в проекции.


проблема может возникнуть из имени метода. Ключевое слово by означает, что вы AE filterig данные по определенному свойству: findByName, например. Его называют создание запроса из имени метода:

http://docs.spring.io/spring-data/jpa/docs/1.10.1.RELEASE/reference/html/#repositories.query-methods.query-creation

С Page<NetworkSimple> findAll(Pageable pageable);


Я думаю, вам нужно создать findAllProjectedBy() как спецификация.Тогда вы можете использовать findAll() способ такой.

пример :findAll(findAllProjectedBy(),pageable)

следующей ссылке, может помочь найти как создать спецификацию весной.

https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/


вы можете использовать:

@Query("SELECT n FROM Network n")
Page<? extends NetworkSimple> findAllProjectedBy(Pageable pageable);

даже с spring-data-jpa 1.11.4, что-то вроде

public interface NetworkRepository extends JpaRepository<Network, String> {
    Page<NetworkSimple> findAll(Pageable pageable);
}

не будет компилироваться; отчетность

findAll(org.springframework.data.domain.Pageable) in NetworkRepository clashes with findAll(org.springframework.data.domain.Pageable) in org.springframework.data.repository.PagingAndSortingRepository
return type org.springframework.data.domain.Page<NetworkSimple> is not compatible with org.springframework.data.domain.Page<Network>

обходной путь, который мы нашли, был переименовать findAll в findAllBy, например,

public interface NetworkRepository extends JpaRepository<Network, String> {
    Page<NetworkSimple> findAllBy(Pageable pageable);
}