Spring Data JPA 参数陷阱:从 500 错误到完美解决的奇妙之旅 ✨

🚀 Spring Data JPA 参数陷阱:从 500 错误到完美解决的奇妙之旅 🌟

嘿,各位技术冒险家!👋 今天我要带你们走进一场 Spring Data JPA 的“参数迷雾”救援行动——从一个让人抓狂的 500 错误,到最终找到真相并解决的全过程!💪 这篇博客不仅有干货,还有代码、流程图和一点小吐槽,快系好安全带,跟我一起跳进这个技术坑吧!😎


🐞 第一幕:500 错误的“神秘来信”

问题登场!😱

我在开发一个分页查询接口,信心满满地丢了个测试 JSON:

{"field": "","page": 0,"size": 10,"value": null
}

结果,服务器毫不留情地回了我一个 500 错误:

"At least 2 parameter(s) provided but only 1 parameter(s) present in query."

啥?参数不匹配?我直接懵圈了。🤦‍♂️


🔍 第二幕:代码探秘与日志线索

我的代码长啥样?🧐

先看看控制器:

@PostMapping("/listInviteCodeByPageWithSearch")
public BaseResult listInviteCodeByPageWithSearch(@SessionAttribute("adminId") Integer adminId,@Valid @RequestBody PageWithSearch pageWithSearch) {try {Page<InviteCode> inviteCodePage = inviteCodeService.findPaginatedInviteCodeByAdminIdAndSearch(adminId, pageWithSearch);return BaseResult.success(inviteCodePage);} catch (Exception e) {return BaseResult.failure(500, "分页查询失败:" + e.getMessage());}
}

再看服务层逻辑:

public Page<InviteCode> findPaginatedInviteCodeByAdminIdAndSearch(Integer adminId, PageWithSearch pageWithSearch) {PageRequest pageRequest = PageRequest.of(pageWithSearch.getPage(), pageWithSearch.getPageSize());String field = pageWithSearch.getField();String value = pageWithSearch.getValue();if (!StringUtils.isEmpty(field) && !StringUtils.isEmpty(value)) {return inviteCodeRepository.findPaginatedInviteCodeByAdminIdAndFieldAndValue(adminId, field, value, pageRequest);} else {return inviteCodeRepository.findByAdminId(adminId, pageRequest);}
}

Repository 接口里有个关键方法:

Page<InviteCode> findByAdminId(Integer adminId, PageRequest pageRequest);

日志说了啥?🕵️‍♂️

我加了日志,输出是这样的:

2025-03-18 21:05:15.840 INFO : Calling findByAdminId
param:adminId args:7
param:pageWithSearch args:PageWithSearch@22e239cd
  • 确认调用了 findByAdminId
  • 参数:adminId = 7pageRequest 基于 page=0, size=10
    一切看起来正常,可为啥报错呢?🤨

🔧 第三幕:揪出元凶,解决问题!

真相大白!💡

问题出在 findByAdminId 的签名:

Page<InviteCode> findByAdminId(Integer adminId, PageRequest pageRequest);
  • Spring Data JPA 期待分页参数是 Pageable,而不是具体的 PageRequest
  • 当我用了 PageRequest,JPA 误以为它是一个查询参数,导致它认为“需要 2 个参数(adminIdpageRequest)”,但实际查询只绑定了 adminId,于是报错了!
Mermaid 流程图:错误发生过程
输入 JSON: field='', value=null
服务层: 判断条件不成立
调用 findByAdminId(adminId, pageRequest)
JPA 解析: adminId=?1, pageRequest=?2
生成 SQL: WHERE admin_id=?1
错误: 参数数量不匹配

修复方案 🛠️

PageRequest 改成 Pageable,问题迎刃而解:

Page<InviteCode> findByAdminId(Integer adminId, Pageable pageable);

服务层调用保持不变(PageRequest 兼容 Pageable):

PageRequest pageRequest = PageRequest.of(pageWithSearch.getPage(), pageWithSearch.getPageSize());
return inviteCodeRepository.findByAdminId(adminId, pageRequest);

再次测试,500 错误消失,数据正常返回!🎉

修复后的流程图
输入 JSON: field='', value=null
服务层: 判断条件不成立
调用 findByAdminId(adminId, pageable)
JPA 解析: adminId=?1, pageable=分页参数
生成 SQL: WHERE admin_id=?1 LIMIT 10 OFFSET 0
成功返回分页数据

🌈 第四幕:经验教训与总结

这次我学到了啥?💡

  1. Spring Data JPA 的分页规范:分页参数必须用 Pageable,别自作主张用 PageRequest
  2. 调试神器:日志 + 流程图,快速定位问题。
  3. 细心点:一个小小的参数类型,就能引发大麻烦。

小建议 🌟

  • 开启 SQL 日志:看看 JPA 到底生成了啥:
    spring.jpa.show-sql=true
    logging.level.org.hibernate.SQL=DEBUG
    
  • Specification:动态查询更灵活,比如:
    Specification<InviteCode> spec = (root, query, cb) -> cb.equal(root.get("adminId"), adminId);
    

🎬 尾声

从 500 错误的迷雾到真相大白,这趟旅程让我又爱又恨 Spring Data JPA。希望这篇博客能帮你在开发路上少踩坑!有问题欢迎留言,咱们一起聊技术!✌️

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35777.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLO obb全流程

内容&#xff1a;xanylabeling 数据标注工具&#xff1b;pytorch&#xff08;python&#xff09;&#xff1b;yolo-obb 模型 一、数据集 1、数据集工具xanylabeling的安装 &#xff08;详细配置与使用方法参考&#xff1a;X-Anylabeling自动标注软件安装使用教程含conda环境…

基于大语言模型与知识图谱的智能论文生成工具开发构想

基于大语言模型与知识图谱的智能论文生成工具开发构想 一、研究背景与意义 1.1 学术写作现状分析 #mermaid-svg-FNVHG5EiEgVSCpHK {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-FNVHG5EiEgVSCpHK .error-icon{fil…

学c++的人可以几天速通python?

学了俩天啊&#xff0c;文章写纸上了 还是蛮有趣的

【计算机网络】一二章

一 二 非常棒的例子 相同的传播时延&#xff0c;带宽越大&#xff0c;该链路上所能容纳的比特数越多 相同的传播时延&#xff0c;带宽越大&#xff0c;该链路上所能容纳的比特数越多 往返时间&#xff08;Round-Trip Time&#xff0c;RTT&#xff09;s是指从发送端发送数据分组…

使用Flask和OpenCV 实现树莓派与客户端的视频流传输与显示

使用 Python 和 OpenCV 实现树莓派与客户端的视频流传输与显示 在计算机视觉和物联网领域&#xff0c;经常需要将树莓派作为视频流服务器&#xff0c;通过网络将摄像头画面传输到客户端进行处理和显示。本文将详细介绍如何利用picamera2库、Flask 框架以及 OpenCV 库&#xff…

Kafka跨集群数据备份与同步:MirrorMaker运用

#作者&#xff1a;张桐瑞 文章目录 前言MirrorMaker是什么运行MirrorMaker各个参数的含义 前言 在大多数情况下&#xff0c;我们会部署一套Kafka集群来支撑业务需求。但在某些特定场景下&#xff0c;可能需要同时运行多个Kafka集群。比如&#xff0c;为了实现灾难恢复&#x…

ECharts仪表盘-仪表盘12,附视频讲解与代码下载

引言&#xff1a; ECharts仪表盘&#xff08;Gauge Chart&#xff09;是一种类似于速度表的数据可视化图表类型&#xff0c;用于展示单个或多个变量的指标和状态&#xff0c;特别适用于展示指标的实时变化和状态。本文将详细介绍如何使用ECharts库实现一个仪表盘&#xff0c;…

Harmony OS【 Tabs 导航篇】

设计图&#xff1a; 代码层&#xff1a; Entry Component struct Index {build() {Tabs({ barPosition: BarPosition.End }) {}.scrollable(false).vertical(false).divider({strokeWidth: 0.5,color: #0d182431}).backgroundColor(#F1f3f5).padding({ top: 36, bottom: 28 }…

兆芯大道云行 | 破解高性能云计算数据存储瓶颈

随着数字化转型的加速和数据安全战略的提升&#xff0c;以及国家政策的驱动&#xff0c;政府、金融、能源等关键领域对数据存储的自主可控要求不断提高&#xff0c;传统依赖国外芯片和技术的集中式存储架构面临安全与扩展性瓶颈。例如&#xff0c;政务云场景中原有的非信创服务…

RSI 量化策略实战指南:基于 iTick 报价源的 Python 实现

一、策略原理 相对强弱指标&#xff08;Relative Strength Index, RSI&#xff09;是由 Welles Wilder 提出的经典技术指标&#xff0c;通过计算价格波动的幅度衡量市场超买 / 超卖状态。RSI 取值范围 0-100&#xff0c;常用判断标准&#xff1a; RSI > 70&#xff1a;超买…

12 File文件对象:创建、获取基本信息、遍历文件夹、查找文件;字符集的编解码 (黑马Java视频笔记)

文章目录 File >> 存储数据的方案1. 认识File2. File操作2.1 创建File对象2.2 File操作1&#xff09;对文件对象的信息的操作2&#xff09;文件/文件夹的创建/删除3&#xff09;⭐⭐对文件夹的遍历 3. 方法递归3.1 认识递归3.2 递归算法及其执行流程1) 案例&#xff1a;2…

逻辑派G1 6层高速板学习

逻辑派G1 6层高速板学习 一、原理图分析二、电源分析三、网表导入四、板框导入五、PCB快捷键导入与设置六、模块抓取以及接口器件布局七、模块化布局--预布局&#xff08;先放各模块中的大器件&#xff09;1 HDMI模块布局2 MCU模块布局3 FPGA模块布局4 DDR3模块布局5 DCDC电源模…

图论——广度优先搜索实现

99. 岛屿数量 题目描述 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。 输入描述 第一行包含两个整数 N, M,表示矩阵的行数和列数。 后续 N 行,每行…

PTS-G1K13M RF Generator 1kW / 13MHz User’s Manual 手侧

PTS-G1K13M RF Generator 1kW / 13MHz User’s Manual 手侧

应用分层简介

一、什么是应用分层 应用分层是一种软件开发设计思想&#xff0c;它将应用程序分为多个层次&#xff0c;每个层次各司其职&#xff0c;多个层次之间协同提供完整的功能&#xff0c;根据项目的复杂程度&#xff0c;将项目分为三层或者更多层。 常见的MCV设计模式&#xff0c;就…

conda的基本使用及pycharm里设置conda环境

创建conda环境 conda create --name your_env_name python3.8 把your_env_name换成实际的conda环境名称&#xff0c;python后边的根据自己的需要&#xff0c;选择python的版本。 激活conda环境 conda activate your_env_name 安装相关的包、库 conda install package_name …

E902基于bash与VCS的仿真环境建立

网上看见很多E902仿真的文章&#xff0c;但用到的编译器是类似于这种Xuantie-900-gcc-elf-newlib-x86_64-V3.0.1-20241120&#xff0c;而我按照相应的步骤与对应的编译器&#xff0c;仿真总会报错。后面将编译器换成riscv64-elf-x86_64-20210512&#xff0c;反而成功了。现在开…

PostgreSQL:简介与安装部署

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

Git使用和原理(3)

1.远程操作 1.1分布式版本控制系统 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地&#xff01;也就是在你的笔记本或者 计算机上。⽽我们的 Git 其实是分布式版本控制系统&#xff01;什么意思呢&a…

ssm框架之mybatis框架讲解

1&#xff0c;Mybatis 1.1 Mybatis概述 1.1.1 Mybatis概念 MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发 MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为MyBatis 。2…