Hibernate带WHERE子句查询异常:无法从数据库获取数据
问题排查与解决方案
嘿,我一眼就看穿问题所在了!先看你报错里最关键的一行:
org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for select queries [select m.id,m.name,m.branch from com.ex.demo.model.Model m where m.id=?]
这个异常直接点明:你给一个SELECT查询调用了executeUpdate()方法,但这个方法只用来执行UPDATE/DELETE这类修改数据的DML语句,完全不支持查询操作,这就是抛出异常的核心原因。
错误代码拆解
你的DAO方法里这段代码是绝对不能留的:
query.executeUpdate();
执行查询语句时调用这个方法,相当于让Hibernate干一件完全不搭的事,不报错才怪。
另外还有两个坑:
- 你的HQL写的是
select m.id,m.name,m.branch,这会返回一个Object[]数组(存着三个字段的值),但你最后要强制转换成Model对象,这后续肯定会报类型转换异常。 query.getFetchSize()不是用来统计查询到的记录数的,它是控制JDBC抓取数据的批次大小,和你要的“获取记录数”完全没关系。
修正后的DAO代码
我帮你把代码改对了,你直接用就行:
public Model readById(Model model) { logger.info("in the read by id - dao method"); System.out.println(model.getId()); String id = model.getId(); // 直接查询整个Model对象,不用拆字段,后续不用类型转换 Query query = currentSession().createQuery("from Model m where m.id = :id"); // 用命名参数代替?,可读性更强,也不容易搞混参数顺序 query.setString("id", id); // 直接获取单个结果,彻底删掉executeUpdate() Model result = (Model) query.getSingleResult(); // 如果要确认是否查到数据,可以这么打印(建议用logger代替System.out) logger.debug("Fetched user: {}", result != null ? result.getName() : "No matching user found"); return result; }
额外优化小技巧
- 处理空结果:
getSingleResult()如果查不到对应ID的记录会抛出NoResultException,建议你加个异常捕获,比如:
try { Model result = (Model) query.getSingleResult(); return result; } catch (NoResultException e) { logger.warn("No user found with id: {}", id); return null; }
这样不会因为查不到数据就直接崩掉。
- 用类型安全的TypedQuery:Hibernate支持泛型Query,不用再强制转换了,代码更安全:
TypedQuery<Model> query = currentSession().createQuery("from Model m where m.id = :id", Model.class); query.setParameter("id", id); Model result = query.getSingleResult();
- 替换System.out:项目里尽量用logger打印日志,方便后续排查问题,也符合规范。
改完之后,你的Controller就能正常拿到完整的Model对象,传给前端页面展示用户信息啦!
内容的提问来源于stack exchange,提问作者totoro
相关产品推荐
相关产品推荐

