JPA命名查询报语法错误,同逻辑MySQL原生查询可正常执行
解决JPA命名查询的语法错误问题
嘿,我明白你遇到的困扰了——你写的嵌套查询在MySQL终端里跑的好好的,但放到JPA的@Query里就报语法错误,对吧?让我帮你捋清楚问题出在哪,以及怎么解决。
问题根源
你现在用的是**HQL(Hibernate Query Language)**来写查询,但HQL并不支持在FROM子句中使用嵌套子查询(也就是派生表),这就是为什么你会看到unexpected token: (的报错——HQL的解析器没法处理这种写法。而你在MySQL终端里执行的是原生SQL,MySQL本身是支持这种嵌套查询的,所以能正常运行。
解决方案:改用原生SQL查询
只需要在@Query注解里加上nativeQuery = true参数,告诉JPA直接执行原生的MySQL语句,而不是解析成HQL。修改后的代码如下:
@Repository public interface CollegeRepository extends CrudRepository<CollegeEntity, Integer> { @Query(value = "SELECT t.* FROM(SELECT *,(((acos(sin((:latitude * pi()/180)) * sin((latitude*pi()/180))+cos((:latitude * pi()/180)) * cos((latitude*pi()/180)) * cos(((:longitude - longitude)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance FROM college) t WHERE distance <= :distance", nativeQuery = true) List<CollegeEntity> getCollegeByLocation(@Param("latitude") Double latitude, @Param("longitude") Double longitude, @Param("distance") Integer distance); }
几点注意事项
- 确保你的
CollegeEntity实体类和数据库表college的映射是正确的(比如通过@Table(name = "college")指定表名),这样JPA才能把原生查询的结果正确映射到实体对象上。 - 原生SQL里的字段名要和数据库表的实际字段名完全一致,而不是实体类的属性名(除非你已经通过
@Column注解把属性和字段名做了映射)。 - 你原来的HQL写法里用了
SELECT c FROM (...) t,这种在HQL里是不合法的,因为HQL是面向实体和属性的查询语言,不能直接操作数据库的表和派生表,所以改用原生SQL是最直接有效的解决方式。
内容的提问来源于stack exchange,提问作者Sagar Yadav
相关产品推荐
相关产品推荐

