web-dev-qa-db-fra.com

Comment utiliser les interfaces de projection avec la pagination dans Spring Data JPA?

J'essaie d'obtenir une page d'une entité partielle (NetworkSimple) en utilisant la nouvelle fonctionnalité de données de printemps, projections

J'ai vérifié la documentation et si je ne demande que:

Collection<NetworkSimple> findAllProjectedBy();

Cela fonctionne, mais si j'utilise pageable:

Page<NetworkSimple> findAllProjectedBy(Pageable pageable);

Cela génère une erreur:

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

Quelqu'un a déjà travaillé avec ça?

Ma classe NetworkSimple est la suivante:

public interface NetworkSimple {
    Long getId();

    String getNetworkName();

    Boolean getIsActive();
}
10
David Magalhães

Remarque: Cette fonctionnalité devrait fonctionner de la manière décrite par l'affiche originale, mais en raison de ce bug cela n'a pas été le cas. Le bogue a été corrigé pour la version Hopper SR2. Si vous êtes bloqué sur une version antérieure, la solution de contournement ci-dessous fonctionnera.

Il est possible d'utiliser Pageable avec les nouvelles fonctionnalités de projection de requête introduites dans Spring Data JPA 1.10 (Hopper). Vous devrez utiliser l'annotation @Query et écrire manuellement une requête pour les champs requis. Ils doivent également être aliasés à l'aide de AS pour permettre à Spring Data de déterminer comment projeter les résultats. Il existe un bon exemple dans spring-boot-samples qui fait partie du référentiel Spring Boot.

Dans votre exemple, ce serait assez simple:

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

J'ai supposé que votre entité ressemblait à ceci:

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

    @Column
    private String name;

    @Column
    private boolean active;

    ...
}

Spring Data dérive automatiquement une requête de comptage pour les informations de pagination. Il est également possible d'utiliser des jointures dans la requête pour extraire des associations, puis les résumer dans la projection.

11
Robert Hunt

Vous pouvez utiliser la projection d'interface avec Pageable comme ceci:

Page<NetworkSimple> findPagedProjectedBy(Pageable pageable);

avec un paramètre:

Page<NetworkSimple> findPagedProjectedByName(String name, Pageable pageable);
0
ema

Même avec spring-data-jpa 1.11.4, quelque chose comme

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

ne pas compiler; rapport 

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>

La solution de contournement trouvée consistait à renommer findAll en findAll By , par exemple.

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

Vous pouvez utiliser:

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

Je pense que vous devez créer findAllProjectedBy() comme spécification. Ensuite, vous pouvez utiliser la méthode findAll() comme ceci.

exemple: findAll(findAllProjectedBy(),pageable)

Le lien suivant peut aider à trouver comment créer une spécification au printemps.

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

0
Hasitha Diluka

Le problème peut provenir du nom de la méthode. Le mot clé by signifie que vous filtrez les données selon une propriété spécifique: findByName, par exemple. Sa création de requête appelée à partir du nom de la méthode:

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

Alors essayez avec Page<NetworkSimple> findAll(Pageable pageable);

0
Michael Desigaud