此示例正常。
@Query("select t from TimeTable t where MONTH(t.date) = ?1 and YEAR(t.date) = ?2")
List<TimeTable> findAll(Integer month, Integer year);
现在我尝试用下面的名字替换?1和?2
@Query("select t from TimeTable t where MONTH(t.date) =month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
这个不起作用并产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException:参数 那个位置[1]不存在;嵌套异常是 java.lang.IllegalArgumentException:具有该位置的参数[1] 不存在
这一个
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException:名称 参数绑定不能为null或为空!在JDK上&lt; 8,你需要 使用@Param作为命名参数,在JDK 8或更高版本上,请务必使用 用-parameters编译。嵌套异常是 java.lang.IllegalArgumentException:参数绑定的名称必须 不是空或空!在JDK上&lt; 8,你需要使用@Param进行命名 参数,在JDK 8或更高版本上,请务必使用-parameters进行编译。
更新:
就像上面的错误所说我不需要在JDK 8上使用@Param,但@Param的解决方案有效:
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
当我删除@Params时再次出现此错误。
答案 0 :(得分:3)
Spring Data查询参数根据其位置进行替换。但这可能会出错,绑定可能容易出错。因此,建议在method参数中使用@Param
注释来绑定查询参数名称。在查询中,您需要使用:paramName
来指示与方法参数绑定相同的paramName
。
按以下方式更新您的方法
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
编译java类时,默认情况下java编译器会更改方法参数名称。假如你编译这段代码
public class Foo {
public void bar(int myHolyParam) {}
}
你最终可能会有这个
public class Foo {
public void bar(int arg0) {}
}
您的参数名称已丢失。您可以通过设置-g:vars
之类的编译器标志来保留名称,但这只会对您的类有所帮助。接口方法参数名称不能保留。在JDK 8罢工之前没有合法的方法可以帮助解决这个问题。你可以在这方面看到这个SO Question。
-parameters
最近,JDK 8提出了解决方案。如果要保留方法参数名称(对于类或接口),可以通过设置-parameter
标志来告诉编译器。利用这个JDK 8特性,Spring可以使用反射推断出参数名称。但请记住,仍然需要使用编译器标志-parameters
才能具备此功能。
因此,如果您没有使用该标志或使用小于8的Java版本,则必须使用@Param
注释来标记参数。
您可以阅读有关Named Parameter in Java 8
的简要介绍答案 1 :(得分:1)
第一个例外是因为你写了=month
而不是=:month
。这样,您只有一个绑定参数,但两个方法参数不匹配。
在第二种情况下,您的字节代码不包含有关参数名称的信息。只需执行异常告诉您的操作:
参数绑定的名称不能为null或为空! 在JDK上&lt; 8,您需要在JDK 8或更高版本上使用@Param作为命名参数,请务必使用-parameters进行编译。
像这样:
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
如果您使用的是Java 8或更高版本,则可以应用错误消息中提供的其他选项:
在JDK 8或更高版本上,请务必使用-parameters进行编译
如果您这样做,则不需要@Param
注释。
有关背景信息,请参阅此问题:Why are Spring Data repository method parameters names not available even on Java 8?
答案 2 :(得分:0)
请为最后一次查询尝试此操作。
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
基于此错误:
你需要在JDK 8或更高版本上使用@Param作为命名参数 一定要用-parameters编译。
请查看here以了解更新问题。