Hibernate创建Query异常:全量查图书正常,筛选查询报错求助
Hibernate异常排查:筛选图书列表失败,全量查询正常
老兄,我来帮你捋一捋这个问题!既然全量获取图书的listBooks()方法完全正常,说明你的Hibernate基础配置、实体映射和DAO的会话管理逻辑都是没问题的,问题肯定出在listBooksFiltered()方法的实现细节里。我给你列几个最常见的坑和排查方向:
一、先看最可能的问题:HQL/JPQL语法错误
这是筛选查询最容易踩的坑,比如参数占位符的写法不对,或者字段名拼写错误。举个例子,如果你在DAO里写了这样的代码:
// 错误写法:参数占位符不能放在引号里 String hql = "from Book where title like '%?1%' and author like '%?2%'"; Query query = session.createQuery(hql); query.setParameter(1, title); query.setParameter(2, author);
这种写法会直接抛出语法异常,因为Hibernate没法识别引号里的?1和?2。正确的写法有两种:
- 使用字符串拼接(HQL参数绑定已做SQL注入防护):
String hql = "from Book where title like ?1 and author like ?2"; Query query = session.createQuery(hql); query.setParameter(1, "%" + title + "%"); query.setParameter(2, "%" + author + "%");
- 使用HQL的
concat函数:
String hql = "from Book where title like concat('%', :title, '%') and author like concat('%', :author, '%')"; Query query = session.createQuery(hql); query.setParameter("title", title); query.setParameter("author", author);
二、空参数处理不当
如果用户没有输入title或author(也就是参数为null或空字符串),直接拼接条件会导致查询异常或者不符合预期。比如当title为null时,title like '%null%'肯定不是你想要的结果。你需要动态拼接查询条件:
@Override public List<Book> listBooksFiltered(String title, String author) { StringBuilder hql = new StringBuilder("from Book where 1=1"); Session session = sessionFactory.getCurrentSession(); if (title != null && !title.trim().isEmpty()) { hql.append(" and title like concat('%', :title, '%')"); } if (author != null && !author.trim().isEmpty()) { hql.append(" and author like concat('%', :author, '%')"); } Query query = session.createQuery(hql.toString()); if (title != null && !title.trim().isEmpty()) { query.setParameter("title", title); } if (author != null && !author.trim().isEmpty()) { query.setParameter("author", author); } return query.list(); }
这种写法会根据参数是否有效动态生成查询语句,避免空参数带来的问题。
三、会话或事务管理不一致
虽然全量查询没问题,但筛选方法可能在会话使用上有差异:
- 你在
listBooks()里用了sessionFactory.getCurrentSession(),但在listBooksFiltered()里误用了sessionFactory.openSession()却没正确关闭会话? - 筛选方法没有在事务中执行?(有些Hibernate配置要求查询必须在事务内)
确保两个方法的会话管理逻辑完全一致,比如都用getCurrentSession(),并且在Service层统一开启事务。
四、实体映射错误
检查Book实体类的title和author字段是否映射正确:
- 有没有用
@Column注解指定正确的数据库列名?比如数据库列是book_title,但实体字段是title却没加@Column(name = "book_title")? - 字段类型是否匹配?比如数据库是
varchar,实体是String没问题,但如果是其他类型就可能出问题。
最后,一定要看具体的异常信息!
Hibernate抛出的异常栈里会有明确的提示,比如QuerySyntaxException就是语法错了,PropertyNotFoundException就是实体属性名写错了。把异常信息贴出来,能更快定位问题!
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

