Hibernate按注册日期查询报String无法转Date类型错误如何解决
错误原因
你遇到的类型转换异常核心是查询参数和实体字段类型不匹配:
你的Contato实体类中dataCadastro字段映射的是java.util.Date类型(对应数据库date/timestamp类型),但查询方法中传入的参数是int类型,Hibernate做参数绑定时无法将int转换为Date类型,因此抛出ClassCastException。
开头的HHH10001501信息是Hibernate自动调整连接自动提交模式的常规提示,不影响业务运行,无需处理。
解决方法
分两种场景处理:
- 场景1:按完整注册日期匹配
- 把查询方法的入参类型从
int修改为java.util.Date - 调用方法前如果拿到的是字符串格式的日期,先通过
SimpleDateFormat或者DateTimeFormatter转换成Date类型再传入
修正后的代码示例:
- 把查询方法的入参类型从
import java.util.Date; import java.text.SimpleDateFormat; // 修改方法入参为Date类型 public void getByDataCadastro(Date dataCadastro) { try(Session session = Util.getSessionFactory().openSession()) { CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery<Contato> criteriaQuery = criteriaBuilder.createQuery(Contato.class); Root<Contato> root = criteriaQuery.from(Contato.class); criteriaQuery.select(root); criteriaQuery.where(criteriaBuilder.equal(root.get("dataCadastro"), dataCadastro)); TypedQuery<Contato> typedQuery = session.createQuery(criteriaQuery); Contato contato = typedQuery.getSingleResult(); System.out.println(contato.getNome() + ", " + contato.getIdade() + ", " + contato.getDataCadastro() ); } catch (Exception e) { e.printStackTrace(); } } // 调用方法示例 public static void main(String[] args) throws Exception{ ContatoDao dao = new ContatoDao(); // 字符串日期转Date后传入 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date queryDate = sdf.parse("2024-01-01 00:00:00"); dao.getByDataCadastro(queryDate); }
- 场景2:按日期的某一部分(年/月/日)查询
如果你的需求是传年份、月份这类数字查询,需要用CriteriaBuilder的日期函数提取字段的对应部分再匹配,不要直接拿数字和Date字段对比,示例代码:
// 按年份查询的示例,入参是年份的int值 public void getByDataCadastroYear(int year) { try(Session session = Util.getSessionFactory().openSession()) { CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery<Contato> criteriaQuery = criteriaBuilder.createQuery(Contato.class); Root<Contato> root = criteriaQuery.from(Contato.class); criteriaQuery.select(root); // 提取dataCadastro的年份和参数对比 criteriaQuery.where(criteriaBuilder.equal( criteriaBuilder.function("YEAR", Integer.class, root.get("dataCadastro")), year )); TypedQuery<Contato> typedQuery = session.createQuery(criteriaQuery); Contato contato = typedQuery.getSingleResult(); System.out.println(contato.getNome() + ", " + contato.getIdade() + ", " + contato.getDataCadastro() ); } catch (Exception e) { e.printStackTrace(); } }
补充注意事项
- 如果匹配完整日期时一直查不到结果,可以用日期函数把数据库字段和参数都截断到相同精度再对比,避免时分秒的精度差异影响匹配
- 建议优先使用Java 8+的
LocalDateTime/LocalDate替换java.util.Date,Hibernate 5+已经原生支持这两类日期类型,不需要额外配置
内容的提问来源于stack exchange,提问作者Mikel Pintto
相关产品推荐
相关产品推荐

