Как использовать проекционные интерфейсы с разбиением на страницы в 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, например. Его называют создание запроса из имени метода:
С 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);
}