使用EntityManager创建PostgreSQL查询时触发ParsingException错误
问题排查与解决方向
核心原因
EntityManager的createQuery()方法默认解析JPQL/HQL(面向实体的查询语言),而非原生PostgreSQL SQL。你传入的是原生SQL语句,导致Hibernate的JPQL解析器无法识别,从而抛出语法解析错误。另外原语句中SELECT*缺少空格,也会加重解析问题。
具体解决方法
方法1:使用原生SQL查询
改用createNativeQuery()方法执行原生SQL,同时注意参数绑定规则:
- 位置参数从
1开始计数,而非0 - 若要使用命名参数,需确保框架支持(比如Hibernate需配置
hibernate.query.native_query.allow_set_parameter_names=true)
修改后的代码示例:
private static final String FIND_USER_BY_NAME = "SELECT * FROM user_details where user_name = ?1 LIMIT 1"; // 位置参数用?1 @Override public User findUserByName(String userName) { TypedQuery<User> query = getEntityManager() .createNativeQuery(FIND_USER_BY_NAME, User.class) .setParameter(1, userName); return query.getSingleResult(); }
方法2:改用JPQL查询(推荐)
JPQL与实体类绑定,而非直接操作数据库表,更符合JPA规范:
- 语句中使用实体类名(如
User)和实体属性名(如userName,需与实体类字段对应) - 用
setMaxResults(1)替代SQL的LIMIT 1
修改后的代码示例:
private static final String FIND_USER_BY_NAME = "SELECT u FROM User u WHERE u.userName = :userName"; @Override public User findUserByName(String userName) { TypedQuery<User> query = getEntityManager() .createQuery(FIND_USER_BY_NAME, User.class) .setParameter("userName", userName) .setMaxResults(1); return query.getSingleResult(); }
额外注意
无论用哪种方式,确保SQL/JPQL语句中的关键字与实体/表名、字段名之间有空格(比如SELECT *而非SELECT*),避免解析器误判。
内容的提问来源于stack exchange,提问作者houhou
相关产品推荐
相关产品推荐

