Hibernate 执行createSQLQuery报Could not instantiate resultclass错误

本文介绍了一个关于Hibernate实例化结果类时出现的错误,并提供了解决方案:为问题类添加无参构造方法。


报的错误信息如下:

出错了。。

错误信息: org.hibernate.HibernateException: Could not instantiate resultclass: com.xxx.xxx.ArticleItemVO

后来发现ArticleItemVO类的构造方法只有

</pre><pre name="code" class="java">public ArticleItemVO(Article article, String nickName, Integer level, String levelDesc, String headPicUrl) {
}



再加上一个无参的构造方法
public ArticleItemVO(){
		
}

然后重新启动就可以解决问题了

`org.hibernate.exception.SQLGrammarException: could not prepare statement` 是 Hibernate 中非常常见的异常,表示 **SQL 语句语法错误或数据库无法准备该语句**。 这个异常通常发生在执行原生 SQL 查询(Native SQL)或 HQL 时,数据库驱动在预编译 SQL 语句时错。 --- ## 🔍 一、常见原因分析 | 原因 | 说明 | |------|------| | 1. SQL 语法错误 | 拼写错误、关键字使用不当、括号不匹配等 | | 2. 表名或字段名不存在 | 数据库中没有对应的表或列 | | 3. 别名冲突或重复 | 多表查询中字段别名重复导致解析失败 | | 4. 使用了数据库保留字作为字段名 | 如 `order`, `group`, `user` 等 | | 5. 参数绑定问题 | `:param` 或 `?` 参数未正确设置或拼接错误 | | 6. 方言(Dialect)不匹配 | 不同数据库(MySQL/Oracle/PostgreSQL)语法差异 | | 7. 字符串拼接导致 SQL 被破坏 | 手动拼接 `'"+value+"'` 容易出错 | --- ## ✅ 二、解决方案与排查步骤 ### ✅ 步骤 1:查看完整异常堆栈日志 确保你看到的是完整的错误信息,例如: ```text org.hibernate.exception.SQLGrammarException: could not prepare statement at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:84) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ... Caused by: com.mysql.cj.jdbc.exceptions.MySQLSyntaxErrorException: Unknown column 'createBm' in 'field list' at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ``` 👉 关键看 **Caused by** 后面的具体数据库错误! 比如上面的例子是: > `Unknown column 'createBm' in 'field list'` → 字段不存在! --- ### ✅ 步骤 2:检查你的 SQL 是否正确 以你之前提到的 SQL 为例: ```java String sql = "select a.id as id,...,b.fdepmc as fdepmc from flowfj a,t_sys_department b where a.createBm=b.fsid and basicId='"+basicId+"' order by createTime"; ``` #### ❌ 存在多个问题: | 问题 | 风险 | |------|------| | 1. 手动拼接 `'"+basicId+"'` | 可能引入非法字符,破坏 SQL 结构 | | 2. 使用 `a.createBm` | 实际字段可能是 `create_bm`(下划线)? | | 3. `t_sys_department` 表是否存在?`fsid` 字段是否存在? | 若表/字段不存在会错 | | 4. `basicId` 是字符串还是数字? | 类型不匹配也会错 | --- ### ✅ 步骤 3:打印并测试 SQL 语句 在 Java 中打印最终 SQL: ```java System.out.println("Generated SQL: " + sql); ``` 然后把输出的 SQL 拿到数据库客户端(如 Navicat、DBeaver、MySQL Workbench)中手动执行,观察是否错。 > ⚠️ 注意:不要直接复制拼接后的 SQL,要模拟真实值代入。 --- ### ✅ 步骤 4:改用参数化查询(强烈推荐) ❌ 错误写法(易出错): ```java "where basicId='" + basicId + "'" ``` ✅ 正确写法(使用命名参数): ```java String sql = """ SELECT a.id AS id, a.basicId AS basicId, a.createBm AS createBm, b.fdepmc AS fdepmc FROM flowfj a INNER JOIN t_sys_department b ON a.createBm = b.fsid WHERE a.basicId = :basicId ORDER BY a.createTime """; return getSessionFactory() .getCurrentSession() .createSQLQuery(sql) .setParameter("basicId", basicId) // 自动转义 .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); ``` 这样可以避免: - SQL 注入 - 引号不匹配 - 特殊字符破坏语句结构 --- ### ✅ 步骤 5:检查数据库字段名大小写和命名规范 不同数据库对大小写敏感性不同: | 数据库 | 是否区分大小写 | |--------|----------------| | MySQL(Linux) | 区分表名、列名(取决于配置) | | Oracle | 默认大写,小写需加双引号 | | PostgreSQL | 默认小写,大写需加双引号 | #### 示例问题: 你在 SQL 写了: ```sql a.createBm = b.fsid ``` 但实际字段可能是: - `CREATEBM`(Oracle 全大写) - `create_bm`(下划线命名) 👉 解决方法:查数据字典,确认真实字段名。 --- ### ✅ 步骤 6:添加 `addScalar()` 显式声明字段类型(可选) 对于复杂查询,建议显式声明字段及其类型: ```java SQLQuery query = session.createSQLQuery(sql); query.setParameter("basicId", basicId); // 显式定义字段和类型 query.addScalar("id", StandardBasicTypes.LONG); query.addScalar("basicId", StandardBasicTypes.STRING); query.addScalar("createBm", StandardBasicTypes.STRING); query.addScalar("fdepmc", StandardBasicTypes.STRING); query.addScalar("createTime", StandardBasicTypes.TIMESTAMP); query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); return query.list(); ``` 有助于 Hibernate 正确解析结果集。 --- ### ✅ 步骤 7:检查 Hibernate Dialect 配置 确保 `hibernate.cfg.xml` 或 `persistence.xml` 中配置了正确的方言: ```xml <!-- MySQL 8 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property> <!-- Oracle 12c --> <property name="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</property> <!-- PostgreSQL --> <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property> ``` 否则某些语法(如分页、函数)可能不兼容。 --- ## ✅ 三、完整修复示例 ```java public List<Map<String, Object>> queryFlowfj(String basicId) { String sql = """ SELECT a.id AS id, a.basicId AS basicId, a.createBm AS createBm, a.createPeo AS createPeo, a.startJyrq AS startJyrq, a.wcrq AS wcrq, b.fdepmc AS fdepmc FROM flowfj a INNER JOIN t_sys_department b ON a.createBm = b.fsid WHERE a.basicId = :basicId ORDER BY a.createTime """; return getSessionFactory() .getCurrentSession() .createSQLQuery(sql) .setParameter("basicId", basicId) .addScalar("id", StandardBasicTypes.STRING) .addScalar("basicId", StandardBasicTypes.STRING) .addScalar("createBm", StandardBasicTypes.STRING) .addScalar("fdepmc", StandardBasicTypes.STRING) .addScalar("startJyrq", StandardBasicTypes.TIMESTAMP) .addScalar("wcrq", StandardBasicTypes.TIMESTAMP) .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); } ``` --- ## ✅ 四、调试技巧总结 | 技巧 | 方法 | |------|------| | 1. 打印 SQL | `System.out.println(sql)` | | 2. 手动执行 SQL | 在数据库工具中运行 | | 3. 查看日志 | 开启 Hibernate SQL 日志:<br>`hibernate.show_sql=true`<br>`hibernate.format_sql=true` | | 4. 查表结构 | `DESC flowfj;` 或 `SELECT * FROM user_tab_cols WHERE table_name='FLOWFJ';`(Oracle) | --- ## ✅ 五、预防措施 | 措施 | 建议 | |------|------| | ✅ 使用参数化查询 | 避免拼接字符串 | | ✅ 统一字段命名规范 | 如全小写下划线 `create_bm` | | ✅ 使用 IDE 插件校验 SQL | 如 MyBatis 插件、Database Navigator | | ✅ 单元测试 DAO 层 | 写测试用例验证 SQL 是否能执行 | --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值