web-dev-qa-db-ja.com

java.lang.IllegalArgumentException:その位置[1]のパラメーターは存在しませんでした

これは私のリポジトリです:

@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);

}

このメソッドを実行しようとすると、例外が発生します。

その位置[1]のパラメーターは存在しません。ネストされた例外はJava.lang.IllegalArgumentException:その位置[1]のパラメーターは存在しませんでした ']

しかしPage<SearchResult>List<SearchResult>すべてが正常に機能します。それは春のバグですか?

[〜#〜] update [〜#〜]:間違っていることがわかったと思います。すべてのパラメーターがwhere句に参加すると、すべてが問題ありません。しかし、少なくとも1つがそこで使用されていない場合、失敗します。しかし、Pageで発生する理由が理解できず、Listを使用する場合は発生しません。そして、それに対処する最良の方法は何ですか?

10
user3861812

クエリをより明確で理解しやすくする@Param( "query_param_name")アノテーションを使用して、クエリを作成できます。

 @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);

 }

このエラーは、スプリングがクエリでメソッドパラメータを入力する場所を見つけられない場合に発生します。したがって、@ Param()アノテーションを使用すると、クエリパラメータとメソッドパラメータが結合され、クエリのsimplecityが増加します。

10
Ashwani Tiwari

私はあなたと同じ問題を抱えていて、最終的にこれらのケースの解決策を見つけました。

私はあなたのような同様の問題を緯度と長いものを計算することで解決しようとしています。

最初は、ページング可能パラメーターを使用することで発生する「カウントクエリ」が問題です。

私は物事をデバッグし、「Pageableを使用する場合、すべての条件なしでWHERE句を使用してカウントクエリを生成する」などのコードを見つけました。

だからこのようにしてみてください。

@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
);
3
NerdHerd

原因Pageは追加のカウントQueryを呼び出す必要がありますが、Listではありません。このエラーは、カウントクエリが原因で発生する必要があります。 ここを参照、ほとんど同じ問題に似ています

1
Yang

同じ問題に直面しました。 Paginationが段階的に機能することを知ってみました。

  1. パラメータに基づくCountの最初のクエリ:Countクエリの[〜#〜] where [〜#〜]句にすべてのパラメータが含まれる場合パラメーターが欠落している場合、パラメーターインデックス番号が欠落しているため、例外が発生します。

その位置[1]のパラメーターは存在しませんでした。ネストされた例外は

  1. データを取得する2番目のクエリ:ここでは、選択したパラメーターを使用する方法があります。

ソリューションvalueおよびcountQueryを使用@ Queryパラメーターを使用して、異なるパラメーター値を使用します。

@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);
0
Nakesh