Java使用JPA原生查询MySQL报错sqlGrammarException无法提取ResultSet
错误原因梳理
- SQL语法错误:查询语句中
WHERE u.uid = = :uid存在多余的等号和空格,SQL语法中等于判断仅需单个等号 - 关联条件错误:
empuser是员工和用户的关联中间表,字段为empid(员工ID)和uid(用户ID),原有语句中JOIN user u ON u.uid = eu.empid关联字段写反,正确关联条件应为u.uid = eu.uid - 返回值不匹配:SQL仅查询了
dob、name、marital三个字段,但方法返回类型是完整的Employee实体,JPA无法将少量字段映射为完整的Employee对象,会导致结果集封装失败
修正方案
方案1:使用JPA关联查询(推荐)
直接依托实体类已定义的关联关系查询,不需要手动写原生SQL,代码更易维护:
@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long>{ // 直接通过关联的EmpUser属性的uid字段查询,JPA自动生成正确SQL Optional<Employee> findByEmpUserUid(Long uid); }
方案2:修正原生SQL写法
如果必须使用原生SQL,需要同步修正语法、关联条件,同时查询完整Employee字段:
@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long>{ @Query(value = "SELECT e.* FROM employee e " + "JOIN empuser eu ON e.empid = eu.empid " + "JOIN user u ON u.uid = eu.uid WHERE u.uid = :uid", nativeQuery = true) Optional<Employee> findEmployeeByUid(@Param("uid") long uid); }
可选优化:投影接收指定字段
如果业务仅需要dob、name、marital三个字段,可定义接口投影接收结果,避免全字段查询的性能损耗:
// 定义投影接口 public interface EmployeeBasicInfo { Date getDob(); String getName(); String getMarital(); } // 调整仓库方法返回类型 @Query(value = "SELECT e.dob, e.name, e.marital FROM employee e " + "JOIN empuser eu ON e.empid = eu.empid " + "JOIN user u ON u.uid = eu.uid WHERE u.uid = :uid", nativeQuery = true) Optional<EmployeeBasicInfo> findEmployeeBasicInfoByUid(@Param("uid") long uid);
内容的提问来源于stack exchange,提问作者Atish Ojha
相关产品推荐
相关产品推荐

