Querydsl复合键查询在Docker/ECS部署后返回空值问题排查
排查Querydsl复合键在Docker/ECS环境返回空的问题
1. 校验Querydsl生成类的一致性
- 确认Docker构建流程中是否正确触发Querydsl代码生成:检查构建脚本(如Dockerfile中的
mvn clean package)是否包含compile阶段,确保querydsl-apt插件正常生成Q类。 - 进入容器解压Jar包,对比
BOOT-INF/classes或generated-sources下的Q类与本地IDE生成版本,重点看复合键字段的映射(如QYourEntity.yourCompositeKey.field1是否和实体类@EmbeddedId/@IdClass定义完全一致)。
2. 对比本地与容器的SQL执行日志
- 在容器环境的配置文件中开启JPA SQL日志:
spring.jpa.show-sql: true spring.jpa.properties.hibernate.format_sql: true logging.level.org.hibernate.type.descriptor.sql: trace - 对比本地和容器输出的SQL语句,重点检查复合键条件的拼接是否正确,是否存在字段大小写不匹配(如数据库区分大小写但容器环境未配置
lower_case_table_names)、参数值是否正确传递。
3. 检查复合键类的equals/hashCode实现
- 确保复合键类(
@EmbeddedId对应的嵌入式类或@IdClass指定的类)正确实现equals()和hashCode():equals()需逐一比较所有主键字段hashCode()需结合所有主键字段生成哈希值
- 容器环境的JVM(如Alpine镜像的轻量JDK)对对象相等性校验更严格,本地能运行的瑕疵实现可能在容器中导致匹配失败。
4. 排查依赖版本与冲突
- 确认Docker构建时的依赖版本与本地完全一致:检查
pom.xml/build.gradle中Querydsl、Spring Boot、JPA的版本号,避免跨版本兼容问题(如Spring Boot 3.x需搭配Querydsl 5.x)。 - 执行
mvn dependency:tree(或gradle dependencies)对比本地和容器环境的依赖树,排查是否存在querydsl-jpa等核心依赖的版本冲突。
5. 验证容器的类加载逻辑
- 添加JVM启动参数
-verbose:class,查看容器中类加载日志,确认Q类、复合键类、实体类的加载顺序是否正常,避免因类加载顺序问题导致映射失效。 - 若使用Spring Boot分层Jar,检查构建配置是否将Querydsl生成类正确打包到可加载的层级,避免类找不到的隐性问题。
6. 简化测试排除干扰
- 编写极简测试接口,仅执行复合键等值查询:
@GetMapping("/test") public List<YourEntity> testCompositeKey() { QYourEntity qEntity = QYourEntity.yourEntity; return queryFactory.selectFrom(qEntity) .where(qEntity.compositeKey.field1.eq("test1"), qEntity.compositeKey.field2.eq("test2")) .fetch(); } - 若该接口仍返回空,直接复制Querydsl生成的SQL到容器连接的数据库中手动执行,确认数据库中是否存在对应数据,排除数据本身的问题。
内容的提问来源于stack exchange,提问作者김태민
相关产品推荐
相关产品推荐

