最近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