Spring Data JPA 何时必须使用@Param注解

最近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参数。

3.不加@Param,在pom.xml的build->plugins中添加如下的代码,指定maven编译时添加-parameters参数。用于线上环境。

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgument>-parameters</compilerArgument>
                </configuration>
            </plugin>

无论采用1,2,3 哪种方案,项目均不再报错。

JPA自定义@Query查询绑定参数的另一种形式是使用 ‘?参数位置’ 来绑定参数(参数位置从1开始计数),这种方式也是JPA默认的参数绑定方式。如下

@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

 

 

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alphathur

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值