如何在 Spring Data JPA 查询中添加 OPTION(RECOMPILE)?
Posted
技术标签:
【中文标题】如何在 Spring Data JPA 查询中添加 OPTION(RECOMPILE)?【英文标题】:How to add OPTION(RECOMPILE) in Spring Data JPA queries? 【发布时间】:2019-07-15 10:57:43 【问题描述】:为了防止在 Sql Server 2012 中出现参数嗅探问题,我想在 JPQL 查询的末尾添加 OPTION(RECOMPILE)。
我把 OPTION(RECOMPILE) 放在查询之后
@Query("SELECT new com.rh.repositorio.modelo.ServidorVisao( "
+ "ser.id, "
+ "ser.matricula, "
+ "ser.nome, "
+ "ser.cpf) "
+ " FROM ServidorBasicoView ser"
+ " WHERE (ser.matricula = :matricula OR :matricula = 0) "
+ " and trim(upper(ser.nome)) like :nome "
+ " and trim(upper(ser.nomeMae)) like :nomeMae and trim(upper(ser.cpf)) like :cpf "
+ " and (ser.dataNascimento = :dataNascimento OR :dataNascimentoStr = null) "
+ " and ser.empresaId = :idEmpresa" +
" OPTION(RECOMPILE)")
Page<ServidorVisao> findServidorBuscaPaginada(@Param("matricula") Long matricula, @Param("nome") String nome,
@Param("nomeMae") String nomeMae, @Param("cpf") String cpf,
@Param("dataNascimento") Date dataNascimento,
@Param("dataNascimentoStr") String dataNascimentoStr,
@Param("idEmpresa") Long idEmpresa,
Pageable pageable);
运行测试我遇到了错误
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: OPTION near line 1, column 449 [SELECT new com.rh.repositorio.modelo.ServidorVisao( ser.id, ser.matricula, ser.nome, ser.cpf) FROM br.com.governa.rh.repositorio.modelo.ServidorBasicoView ser WHERE (ser.matricula = :matricula OR :matricula = 0) and trim(upper(ser.nome)) like :nome and trim(upper(ser.nomeMae)) like :nomeMae and trim(upper(ser.cpf)) like :cpf and (ser.dataNascimento = :dataNascimento OR :dataNascimentoStr = null) and ser.empresaId = :idEmpresa OPTION(RECOMPILE)]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:296) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:188) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:595) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:704) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
... 132 common frames omitted
【问题讨论】:
【参考方案1】:您必须将选项 nativeQuery 设置为 true,即
@Query(value=«select * from foo OPTION(RECOMPILE)»,nativeQuery=true)
【讨论】:
以上是关于如何在 Spring Data JPA 查询中添加 OPTION(RECOMPILE)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Data (JPA) 派生查询中按多个属性排序?
如何在不使用查询缓存的情况下缓存 Spring Data JPA 查询方法的结果?
如何在spring data jpa中进行POJO投影以进行本机查询
如何更新 Spring Data JPA @Modifying @Query 查询中的 JPA/Hibernate @Version 字段?