MySQL 5升级至8后使用nativeQuery查询遇表/列不存在问题求助
解决MySQL 8升级后Hibernate nativeQuery相关问题
方案1:避免使用nativeQuery,用HQL分页替代limit
HQL本身不支持limit关键字,这是原生SQL语法。MySQL 5时期Hibernate可能做了兼容,但升级到8后语法校验更严格,直接用Hibernate的分页API即可解决:
- Spring Data JPA场景:在Repository方法中添加
Pageable参数List<StudQuesAttemptBO> findByXXX(Pageable pageable); - 手动HQL场景:调用
setFirstResult()和setMaxResults()实现分页Query query = session.createQuery("from StudQuesAttemptBO where ..."); query.setFirstResult(0); // 起始索引 query.setMaxResults(10); // 每页数量 List<StudQuesAttemptBO> result = query.list();
这种方式无需开启nativeQuery,还能避免表名、列名不匹配的问题。
方案2:必须使用nativeQuery时,修正SQL语法
nativeQuery执行的是原生SQL,必须完全使用数据库的实际表名和列名,不能用实体类的名称:
- 表名修正:实体类
StudQuesAttemptBO映射的是student_question_attempt表,SQL里必须写这个实际表名,而非实体类名studquesattemptbo - 列名修正:实体类属性
questionBO对应数据库中的实际列名(比如question_id,以实体类@Column注解为准),SQL里要写数据库列名,或者用别名匹配实体类属性名
- 返回实体类的示例SQL:
注意:别名要和实体类属性名一致,同时实体类属性需通过@Column注解指定对应数据库列名。@Query(value = "select sqla.id as id, sqla.question_id as questionBO from student_question_attempt sqla where ... limit ?1, ?2", nativeQuery = true) List<StudQuesAttemptBO> findWithLimit(int offset, int limit);
额外检查项
- 确认
lower_case_table_names=1生效:重启MySQL后执行show variables like 'lower_case_table_names';查看值是否为1 - 核对实体类@Table注解:确保
@Table(name = "student_question_attempt")配置正确,无拼写错误 - 清理Hibernate缓存:升级数据库后可能存在旧元数据缓存,重启Tomcat即可清除
内容的提问来源于stack exchange,提问作者rob
相关产品推荐
相关产品推荐

