Spring自定义删除查询未识别传入参数、执行时显示问号是什么原因?
问题原因及解决方案
首先需要先区分你遇到的是两种情况中的哪一种:
情况1:删除功能实际运行正常,仅日志显示?占位符
这是Hibernate的默认日志机制导致的,默认只会打印SQL框架,不会输出实际绑定的参数值,不属于参数未替换的功能异常。
如果需要在日志中查看实际参数值,修改项目配置文件即可:
yml配置示例:
logging: level: org.hibernate.SQL: debug org.hibernate.type.descriptor.sql.BasicBinder: trace
properties配置示例:
logging.level.org.hibernate.SQL=debug logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
配置完成后重启项目,即可在日志中看到参数绑定的详细内容,可以用来确认参数是否正确传递。
情况2:删除操作实际执行失败,参数未生效
你可以按照以下步骤修改排查:
- 简化SQL参数绑定写法,你当前使用的
:#{#xxx}是SpEL表达式写法,普通参数绑定无需使用该语法,修改为如下写法即可:
@Modifying @Transactional @Query(value = "DELETE FROM game_like WHERE player_id=:playerId AND game_id=:gameId", nativeQuery = true) void deleteReference(@Param("playerId") Long player, @Param("gameId") Long game);
- 排查多对多关联配置的影响:你配置了
player和game的多对多关联,直接手动删除中间表数据可能会和JPA的持久化上下文缓存不同步,导致操作不生效。更推荐用JPA规范的关联操作方式,不需要自定义删除SQL:
// 业务层代码示例 @Transactional public void removeGameRelation(Long playerId, Long gameId) { Player player = playerRepository.findById(playerId).orElseThrow(); Game game = gameRepository.findById(gameId).orElseThrow(); player.getGames().remove(game); playerRepository.save(player); }
该方式会自动维护中间表数据,避免缓存与数据库数据不一致的问题。
内容的提问来源于stack exchange,提问作者Isak Holmström
相关产品推荐
相关产品推荐

