Spring Data JPA带条件的限制查询抛出NumberFormatException问题求助
解决Spring Data JPA中限制查询与条件查询组合的问题
我来帮你搞定这个坑~先回顾下你的场景:
你定义的实体类是这样的:
@Entity @Table(name = "MESSAGE") public class MessageEntity { @Id @Column(name = "ID") private Long id; @Column(name = "TRACE_ID", nullable = false) private String traceId; @Column(name = "REGISTRATION", nullable = false) private LocalDateTime registration; }
然后你在Repository里写了这两个方法:
public interface MessageJpaRepository extends JpaRepository<MessageEntity, Long> { MessageEntity getFirstByTraceId(String traceId); MessageEntity getFirst1ByTraceId(String traceId); }
调用的时候抛出了NumberFormatException,原因是Spring Data JPA把你的traceId字符串参数误当成了limit的数字参数来解析,自然转类型就报错了。改成List也没用,因为方法名的解析逻辑还是错的。
正确的写法有两种,核心是明确告诉框架参数的作用:
1. 结合排序条件,明确方法名结构
Spring Data JPA需要明确知道你要“按什么排序取第一条”,所以给方法名加上排序规则就行:
// 用getFirst或者findFirst都可以 MessageEntity getFirstByTraceIdOrderByRegistrationDesc(String traceId); // 或者 MessageEntity findFirstByTraceIdOrderByRegistrationDesc(String traceId);
这样框架会正确生成SQL:先过滤TRACE_ID匹配的记录,再按REGISTRATION倒序排序,最后取第一条。
2. 使用TopN的写法明确限制数量
如果你不需要排序(不过不排序的话“第一条”是随机的,不推荐),可以用Top1来明确要取1条:
MessageEntity findTop1ByTraceId(String traceId);
如果需要排序,同样加上排序条件更严谨:
MessageEntity findTop1ByTraceIdOrderByRegistrationDesc(String traceId);
为什么原来的写法不行?
Spring Data JPA的方法名解析规则里,First/Top后面如果没有紧跟数字(比如Top1)或者排序关键字(OrderBy...),框架会错误解析方法的结构,把后面的条件参数当成了限制结果数量的参数,所以才会把字符串traceId尝试转成数字,抛出NumberFormatException。
只要把方法名调整成上面两种格式,就能正确区分条件参数和限制逻辑啦~
内容的提问来源于stack exchange,提问作者TomVW
相关产品推荐
相关产品推荐

