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();
}
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.
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);
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);
}
Vous pouvez utiliser:
@Query("SELECT n FROM Network n")
Page<? extends NetworkSimple> findAllProjectedBy(Pageable pageable);
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/
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:
Alors essayez avec Page<NetworkSimple> findAll(Pageable pageable);