Spring6+Hibernate6升级后JpaRepository无法解析id属性问题
问题分析
Spring Data JPA 内置方法(如findById)自动生成的SQL中,使用了小写的id列名去查询数据库中大写的ID列,导致数据无法匹配。而自定义@Query方法因为手动指定了正确的列名,所以可以正常工作。这是由于Hibernate 6对标识符字段(@Id)的映射解析逻辑发生了变化,或者Spring Data JPA生成查询时未正确读取@Column(name = "ID")的配置。
解决方案
方案1:自定义Hibernate物理命名策略(全局生效,无需修改仓库/实体)
自定义一个物理命名策略,强制将实体中的id字段映射到数据库的ID列,其他字段保持原有命名规则:
- 创建自定义命名策略类:
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; public class UppercaseIdPhysicalNamingStrategy extends SpringPhysicalNamingStrategy { @Override protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) { // 仅对名为"id"的字段转为大写列名 if ("id".equals(name)) { return new Identifier("ID", quoted); } // 其他字段沿用Spring默认的命名策略(驼峰转下划线小写) return super.getIdentifier(name, quoted, jdbcEnvironment); } }
- 在配置文件中指定该策略:
application.properties
spring.jpa.hibernate.naming.physical-strategy=com.yourpackage.UppercaseIdPhysicalNamingStrategy
application.yml
spring: jpa: hibernate: naming: physical-strategy: com.yourpackage.UppercaseIdPhysicalNamingStrategy
方案2:修正实体类@Column注解(全局修改实体,比改仓库更高效)
如果所有实体的ID字段都映射到数据库的ID列,可以通过IDE全局替换功能批量修改实体中@Id字段的@Column注解,去掉反引号(Hibernate 6对引号的处理逻辑有变化):
@Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "uuid2") @JsonProperty("ID") @Column(name = "ID", length = 36) // 去掉反引号` private String id;
方案3:全局配置Spring Data JPA的查询生成规则
通过配置强制Spring Data JPA优先使用实体映射的列名生成查询,需结合Hibernate命名策略生效:
application.properties
spring.data.jpa.query-generation-strategy=USE_DECLARED_QUERY
验证方法
启动应用后,开启SQL日志查看自动生成的SQL语句,确认findById使用的是ID列名:
application.properties
spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true
内容的提问来源于stack exchange,提问作者Kirill Vizniuk
相关产品推荐
相关产品推荐

