在JpaRepository查询中使用snake case报错该如何解决?
JpaRepository方法名使用snake_case报错解决方案
报错核心原因
你遇到的报错由两个底层规则导致:
- Spring Data JPA的方法名解析规则中,单下划线是保留关键字,用于分隔嵌套对象的属性。你写
findParticipantByGame_a时,JPA会误认为你要找Participant类的game属性下的a子属性,自然匹配不到对应字段。 - Java编码规范默认要求类属性使用小驼峰命名,你不需要为了适配数据库的snake_case字段强行把Java属性改成下划线命名,两者靠JPA的命名映射规则即可关联。你之前尝试
findParticipantByGameA不生效,是因为没有同步修改实体类的属性名为gameA,JPA找不到对应属性自然报错。
方案1(推荐):遵循Java规范,靠命名策略自动映射
这是行业通用的标准实现,不需要修改数据库字段,仅需调整Java代码和配置即可:
- 首先修改
Participant实体类的属性为小驼峰命名:
// 实体类属性使用标准小驼峰 private Game gameA;
- 确认项目配置中开启了驼峰转下划线的命名映射,Spring Boot 2.3+版本默认已经开启该配置,未开启的话手动添加配置即可:
# application.yml 配置示例 spring: jpa: hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
这个配置会自动把Java的驼峰属性映射为数据库的snake_case字段,也就是gameA属性自动对应数据库的game_a字段,和你原生SQL的字段完全匹配。
3. 最后修改仓储层方法名,直接用驼峰属性名编写即可:
@Repository public interface ParticipantRepository extends JpaRepository<Participant, Long> { List<Participant> findByGameA(Game gameA); }
该方法最终生成的SQL会自动拼接where game_a = ?,完全符合你需要的查询逻辑。
方案2(不推荐):保留Java属性的snake_case命名
如果确实有特殊原因不能修改实体类属性名,可以用双下划线转义方法名里的下划线,告诉JPA这个下划线是属性名的一部分,不是分隔符:
- 实体类属性保持snake_case的同时,建议显式指定映射的数据库字段避免歧义:
@Column(name = "game_a") private Game game_a;
- 仓储层方法名用双下划线代替单下划线:
@Repository public interface ParticipantRepository extends JpaRepository<Participant, Long> { List<Participant> findByGame__a(Game game_a); }
注意:该方案不符合Java编码规范,后续维护成本更高,仅作为应急方案使用。
内容的提问来源于stack exchange,提问作者Oliver Šmakal
相关产品推荐
相关产品推荐

