Voici mon référentiel:
@Repository
public interface MyRepository extends JpaRepository<Entity, Long> {
public static final String DISTANCE = "((acos(sin(?1 * pi() / 180) * sin(a.latitude * pi() / 180) + cos(?1 * pi() / 180) * cos(a.latitude * pi() / 180) * cos((?2 - a.longitude) * pi() / 180)) * 180 / pi()) * 60 * 1.609344) as distance";
@Query("select new package.SearchResult(" + DISTANCE + ", a.addressOwner) from Address a group by a.addressOwner, col_0_0_ having col_0_0_ < ?3 order by col_0_0_")
public Page<SearchResult> findClosestByCoordinates(double lat, double lng, double maxDistance, Pageable pageable);
}
Lorsque j'essaie d'exécuter cette méthode, une exception se produit:
Le paramètre avec cette position [1] n'existait pas; l'exception imbriquée est Java.lang.IllegalArgumentException: Le paramètre avec cette position [1] n'existait pas ']
Mais quand je remplace Page<SearchResult>
avec List<SearchResult>
tout fonctionne très bien. Est-ce le bug de Spring ou quelque chose?
UPDATE : Je suppose que j'ai trouvé ce qui ne va pas: quand TOUS les paramètres participent à la clause where, tout va bien. Mais si au moins l'un d'entre eux n'y est pas utilisé, il échoue. Mais je ne comprends pas pourquoi cela se produit avec Page et ne se produit pas lorsque vous utilisez List. Et quelle est la meilleure façon d'y faire face?
Vous pouvez rendre la requête en utilisant l'annotation @Param ("query_param_name") qui rend la requête plus claire et compréhensible.
@Repository
public interface MyRepository extends JpaRepository<Entity, Long> {
public static final String DISTANCE = "((acos(sin(:lat * pi() / 180) * sin(a.latitude * pi() / 180) + cos(:lat * pi() / 180) * cos(a.latitude * pi() / 180) * cos((:lng - a.longitude) * pi() / 180)) * 180 / pi()) * 60 * 1.609344) as distance";
@Query("select new package.SearchResult(" + DISTANCE + ", a.addressOwner) from Address a group by a.addressOwner, col_0_0_ having col_0_0_ < :maxDistance order by col_0_0_")
public Page<SearchResult> findClosestByCoordinates(@Param("lat")double lat, Param("lng")double lng, @Param("maxDistance") double maxDistance, Pageable pageable);
}
Cette erreur survient lorsque le printemps ne trouve pas où saisir le paramètre de méthode dans la requête. Ainsi, l'utilisation de l'annotation @Param () lie le paramètre de requête et le paramètre de méthode ensemble et augmente la simplicité de la requête
J'avais le même problème avec vous et j'ai finalement trouvé une solution pour ces cas.
J'essaie de résoudre un problème similaire comme vous en calculant des choses longues et latentes.
Au début, le problème est "Count Query" causé par l'utilisation du paramètre Pageable.
J'ai débogué des choses et trouvé des codes comme "lors de l'utilisation de Pageable, générer une requête de comptage avec des clauses WHERE SANS CHAQUE CONDITION".
Alors essayez comme ça.
@Query(value = "FROM MemberEntity mem " +
"WHERE mem.seq != :selfSeq AND " +
"get_distance_in_kilos_between_geo_locations(" +
":lat, " +
":lon, " +
"mem.recentLocationLog.latitude, " +
"mem.recentLocationLog.longitude" +
") > :pageId " +
"ORDER BY get_distance_in_kilos_between_geo_locations(" +
":lat, " +
":lon, " +
"mem.recentLocationLog.latitude, " +
"mem.recentLocationLog.longitude" +
") ASC "// +
,
countQuery = "SELECT COUNT(1) FROM MemberEntity mem " +
"WHERE mem.seq != :selfSeq AND " +
"get_distance_in_kilos_between_geo_locations(" +
":lat, " +
":lon, " +
"mem.recentLocationLog.latitude, " +
"mem.recentLocationLog.longitude" +
") > :pageId "
)
Page<MemberEntity> findByDistanceAndExcludeSelf(
@Param("lat") double latitude,
@Param("lon") double longitude,
@Param("selfSeq") long selfSeq,
@Param("pageId") double pageId,
Pageable pageable
);
Cause La page doit appeler une requête de comptage supplémentaire, mais Liste pas. Cette erreur doit être provoquée par le nombre de requêtes. Voir ici, plus comme le même problème
J'ai fait face au même problème. Après quelques essais, j'ai appris que Pagination fonctionne en phases.
Le paramètre avec cette position [1] n'existait pas; l'exception imbriquée est
Solution: utilisez valeur et countQuery à l'intérieur @ Query paramètre pour utiliser différentes valeurs de paramètre.
Par exemple
@Query(value = "SELECT * FROM Shop s WHERE pincode = :pin",
countQuery = "SELECT COUNT(1) FROM Shop s WHERE pincode = :pin AND shoptitle = :title")
Page<Shop> findShopForPincode(@Param("pin") String pin, @Param("title") String title);