java.lang.IllegalArgumentException:该位置[1]的参数不存在

时间:2015-08-27 15:59:54

标签: spring-data-jpa jpql

这是我的存储库:

@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]不存在&#39;]

但是当我用 Page<SearchResult> 替换 List<SearchResult> 时,一切正常。是春天的小虫还是什么?

UPDATE :我想我发现了什么错误:当所有参数都参与where子句时,一切正常。但如果其中至少有一个没有在那里使用,那就失败了。但我不明白为什么它会在Page中发生,并且在使用List时不会发生。处理它的最佳方法是什么?

4 个答案:

答案 0 :(得分:10)

您可以使用@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);

 }

当spring找不到在查询中输入方法参数的位置时会出现此错误。 因此,使用@Param()注释将查询参数和方法参数绑定在一起并增加查询的简单性

答案 1 :(得分:3)

我和你有同样的问题,最后找到了这些案例的解决方案。

我试图像你一样解决类似的问题,计算lat,很长的事情。

首先,问题是&#34; Count Query&#34;使用Pageable参数引起的。

我调试了一些东西并发现了一些代码,例如&#34;当使用Pageable时,使用WHERE子句生成计数查询,没有每个条件&#34;。

所以试试这个。

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

答案 2 :(得分:1)

原因页面需要调用额外的计数查询,但列表不需要。此错误必须由count Query引起。 See here, most like same problem

答案 3 :(得分:0)

我遇到了同样的问题。经过一番尝试后才知道分页分阶段进行。

  1. 根据您的参数首先查询计数:包括计数查询的 WHERE 子句中的每个参数,如果您错过了任何参数参数将在错过参数索引号
  2. 的异常下面得到
      

    该位置[1]的参数不存在;嵌套异常是

    1. 检索数据的第二个查询:这里有一种方法可以使用您选择的参数。
    2. 解决方案:在 @Query 参数中使用 countQuery 来使用不同的参数值。

      例如

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