最近JPA踩坑,使用自定义的@Query报出下面的异常:
org.springframework.dao.InvalidDataAccessApiUsageException: For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.; nested exception is java.lang.IllegalStateException: For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.
其实异常提示的很明显了,你需要使用@Param指定参数名称是什么,或者当你的编译器版本大于1.8的时候要对编译参数加上-parameters。
当前代码实体类和视图对象如下:
@Data
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; // 主键
private Integer age;
private String name;
private Double salary;
private String address;
}
@Value
@ToString
public class StudentVo {
private String name;
private Integer age;
}
通过@Query注解返回视图对象列表 :
public interface StudentRepository extends CrudRepository<Student, Integer> {
@Query(
"select new com.alphathur.jpademo.model.vo.StudentVo(name, age) from Student where salary = :salary ")
List<StudentVo> findStudentVo(Double salary);
}
这个接口使用了‘ :参数名’ 来绑定参数,且没有对salary使用@Param参数,所以报错了。
这里提供两种方案解决问题:
1.加上@Param,将接口修改如下:
public interface StudentRepository extends CrudRepository<Student, Integer> {
@Query(
"select new com.alphathur.jpademo.model.vo.StudentVo(name, age) from Student where salary = :salary ")
List<StudentVo> findStudentVo(@Param("salary") Double salary);
}
2.不加@Param,修改idea的编译器参数。
如图选择 Preferences -> Build, Execution, Deployment -> Compiler -> Java Compiler.对当前项目加入-parameters参数。
无论采用1,2 哪种方案,项目均不再报错。
JPA自定义@Query查询绑定参数的另一种形式是使用 ‘?参数位置’ 来绑定参数(参数位置从1开始计数)。如下
@Query(
"select new com.alphathur.jpademo.model.vo.StudentVo(name, age) from Student where salary = ?1 and age = ?2 ")
List<StudentVo> findStudentVoBySalaryAndAge(Double salary, Integer age);
这种查询即使不加@Param,编译器不做任何设置,也不会报错。
总结:
当使用JPA的@Query来自定义查询,如果选择了参数名的绑定方式,当编译器级别大于等于1.8且添加了-parameters,则可以不加@Param,否则必须添加@Param。
参考JPA官方手册:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters