当MongoDB主键为String时,mongoTemplate无法根据id查询的问题

MongoDB推荐使用ObjectId作为主键,但国内的开发都知道,事情往往不如人所愿,当我们真的出现了“_id”主键的类型为String时,且还必须想用mongoTemplate.findOne或findList时,直接使用该方法会导致查询结果为空。

因为mongoTemplate会在查询的时候将主键转换为ObjectId。

实际上这一步转换是MappingMongoConverter中做的,源码如下:

	/*** Converts the given raw id value into either {@link ObjectId} or {@link String}.** @param id can be {@literal null}.* @param targetType must not be {@literal null}.* @return {@literal null} if source {@literal id} is already {@literal null}.* @since 2.2*/
@Nullabledefault Object convertId(@Nullable Object id, Class<?> targetType) {if (id == null || ClassUtils.isAssignableValue(targetType, id)) {return id;}if (ClassUtils.isAssignable(ObjectId.class, targetType)) {if (id instanceof String) {if (ObjectId.isValid(id.toString())) {return new ObjectId(id.toString());}// avoid ConversionException as convertToMongoType will return String anyways.return id;}}try {return getConversionService().canConvert(id.getClass(), targetType)? getConversionService().convert(id, targetType): convertToMongoType(id, (TypeInformation<?>) null);} catch (ConversionException o_O) {return convertToMongoType(id,(TypeInformation<?>)  null);}}

注意示例版本为spring-data-mongodb:3.3.5,一些更古早的版本,如2.1.9,需要重写其他部分,如果有人需要请留言,我会抽时间补充,但鉴于之前的版本有比较重大的漏洞,所以推荐升级版本。

 if (ObjectId.isValid(id.toString())) { return new ObjectId(id.toString()); }

这段就是mongoTemplate将String转换为ObjectId的步骤。

所以我们要做的就是重写这部分,并且替换掉原有的:

1、新建一个Converter

public class MyMongoConverter extends MappingMongoConverter {public MyMongoConverter(DbRefResolver dbRefResolver, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {super(dbRefResolver, mappingContext);}@Overridepublic Object convertId(@Nullable Object id, Class<?> targetType) {if (id == null || ClassUtils.isAssignableValue(targetType, id)) {return id;}if (ClassUtils.isAssignable(ObjectId.class, targetType)) {if (id instanceof String) {return id;}}try {return getConversionService().canConvert(id.getClass(), targetType)? getConversionService().convert(id, targetType): convertToMongoType(id, (TypeInformation<?>) null);} catch (ConversionException o_O) {return convertToMongoType(id,(TypeInformation<?>)  null);}}
}

2、在构建MongoTemplate时用我们自己写的替换

MongoTemolate mongoTemplate = new MongoTemplate(mongoDbFactory(), getDefaultMongoConverter(mongoDbFactory()))protected static MongoConverter getDefaultMongoConverter(MongoDatabaseFactory factory) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);MongoCustomConversions conversions = new MongoCustomConversions(Collections.emptyList());MongoMappingContext mappingContext = new MongoMappingContext();mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());mappingContext.afterPropertiesSet();MyMongoConverter converter = new MyMongoConverter(dbRefResolver, mappingContext);converter.setCustomConversions(conversions);converter.afterPropertiesSet();converter.setTypeMapper(new DefaultMongoTypeMapper(null));return converter;}/*** @return {@link MongoDatabaseFactory}*/protected MongoDatabaseFactory mongoDbFactory() {ServerAddress serverAddress = new ServerAddress(host, port);MongoClientSettings.Builder setting = MongoClientSettings.builder().applyToClusterSettings(builder -> builder.hosts(Collections.singletonList(serverAddress))).retryWrites(false);if (ObjectUtil.isNotEmpty(username)) {MongoCredential credential = MongoCredential.createCredential(username, authenticationDatabase, password.toCharArray());setting.credential(credential);}MongoClient mongoClient = MongoClients.create(setting.build());return new SimpleMongoClientDatabaseFactory(mongoClient, database);}

host,port,username,authenticationDatabase,password,database

分别为MongoDB的地址,端口号,用户名,认证数据库,密码,数据库名

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

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

相关文章

https 协议

目录 加密方式 对称加密 非对称加密 非对称加密 非对称加密 非对称加密 对称加密 AC证书 AC证书内容 数据摘要 数据签名 在我们前面学习的http协议里面&#xff0c;我们发送的内容都是明文传输的&#xff0c;所以在安全上并不安全&#xff0c;但是在现在信息发达的时…

Java高级技术:优化性能与扩展性的最佳实践

标题&#xff1a;Java高级技术&#xff1a;优化性能与扩展性的最佳实践 摘要&#xff1a;本文将介绍Java中一些高级技术&#xff0c;以提高性能和代码的扩展性。本文不包括反射和并发编程&#xff0c;旨在帮助开发者进一步提升Java应用程序的质量和可维护性。 优化性能的最佳实…

面试题目总结(三)

1. Spring、Springboot、springMVC、Spring Cloud 的区别&#xff1a; Spring&#xff1a;Spring 是一个开源的、轻量级的Java框架&#xff0c;提供了丰富的功能和组件&#xff0c;用于构建企业级应用程序。Spring框架包含了很多模块&#xff0c;包括核心容器、数据访问、事物…

MATLAB算法实战应用案例精讲-【数模应用】漫谈机器学习(七)

目录 几个高频面试题目 机器学习算法工程师需要掌握哪些编程语言? 1.Python 2. C# 3.JavaScript 4. R 5.Java

Linux之Apache服务器安装及配置

一、Apache服务器简介 Apache HTTP Server&#xff08;简称Apache&#xff09;是Apache软件基金会的一个开放源码的网页服务器&#xff0c;可以在大多数计算机操作系统中运行&#xff0c;由于其多平台和安全性被广泛使用。Apache曾经是世界使用排名第一的Web服务器软件&#xf…

VSCODE连接远程服务器

安装ssh插件 根据你的操作系统选择对应的版本进行下载和安装。 安装完成之后&#xff0c;启动vscode&#xff0c;选择左侧Extensions 选项卡&#xff0c;在输入框搜索 remote &#xff0c;选择安装Remote-SSH插件。 安装完成之后会在左侧新增一个选项卡Remote Explorer&#xf…

肥猫游戏报价器|计价器|王者荣耀代练陪练等游戏报价器软件介绍说明

目录 1. 前言2. 软件著作权3. 软件使用说明3.1 进入软件3.2 用户登录3.3 首页3.4 报价器3.4.1 总体介绍3.4.2 王者报价器3.4.3 LOL手游报价器3.4.4 英雄联盟报价器3.4.5 云顶之弈报价器3.4.7 王者水晶报价器3.4.8 和平精英报价器3.4.9 蛋仔派对报价器3.4.10 穿越火线报价器3.4.…

kafka学习笔记--broker工作流程、重要参数

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

Linux mc命令教程:如何有效地使用mc命令(附案例详解和注意事项)

Linux mc命令介绍 mc命令是Linux中的一个视觉文件管理器&#xff0c;全称为Midnight Commander。它提供了一个用户友好的界面&#xff0c;使得在Linux环境中的文件和目录管理变得更加直观和方便。mc命令支持鼠标操作和颜色显示&#xff0c;同时也提供了一套菜单接口&#xff0…

TypeScript 常用高级类型

目录 前言&#xff1a; TypeScript 常用高级类型 基本概念 高级类型 1. 交叉类型&#xff08;Intersection Types&#xff09; 2. 联合类型&#xff08;Union Types&#xff09; 3. 映射类型&#xff08;Mapped Types&#xff09; 4. 条件类型&#xff08;Conditional…

GGML 或GGUF的14种不同量化模式说明

查看 TheBloke/Llama-2–13B-chat-GGML 存储库中的文件&#xff0c;我们可以看到 14 种不同的 GGML 模型&#xff0c;对应于不同类型的量化。它们遵循特定的命名约定&#xff1a;“q” 用于存储权重的位数&#xff08;精度&#xff09; 特定变体。以下是所有可能的量化方法及其…

Pytorch-Transformer轴承故障一维信号分类(三)

目录 前言 1 数据集制作与加载 1.1 导入数据 第一步&#xff0c;导入十分类数据 第二步&#xff0c;读取MAT文件驱动端数据 第三步&#xff0c;制作数据集 第四步&#xff0c;制作训练集和标签 1.2 数据加载&#xff0c;训练数据、测试数据分组&#xff0c;数据分batch…

据房间Id是否存在,判断当前房间是否到期且实时更改颜色

重点代码展示&#xff1a; <template><el-col style"width: 100%;height: 100%;"><el-col :span"20"><el-card class"room_info"><avue-data-icons :option"option"></avue-data-icons></el-…

RT-DETR算法优化改进:轻量化自研设计双卷积重新设计backbone和neck,完成涨点且计算量和参数量显著下降

💡💡💡本文自研创新改进:双卷积由组卷积和异构卷积组成,执行 33 和 11 卷积运算代替其他卷积核仅执行 11 卷积,YOLOv8 Conv,从而轻量化RT-DETR,性能如下表,GFLOPs 8.1降低至7.6,参数量6.3MB降低至5.8MB RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_637742…

ubuntu-c++-可执行模块-动态链接库-链接库搜索-基础知识

文章目录 1.动态链接库简介2.动态库搜索路径3.运行时链接及搜索顺序4.查看可运行模块的链接库5.总结 1.动态链接库简介 动态库又叫动态链接库&#xff0c;是程序运行的时候加载的库&#xff0c;当动态链接库正确安装后&#xff0c;所有的程序都可以使用动态库来运行程序。动态…

Android帝国之日志系统--logd、logcat

本文概要 这是Android系统进程系列的第四篇文章&#xff0c;本文以自述的方式来介绍logd进程&#xff0c;通过本文您将了解到logd进程存在的意义&#xff0c;以及日志系统的实现原理。&#xff08;文中的代码是基于android13&#xff09; Android系统进程系列的前三篇文章如下…

C#基础与进阶扩展合集-基础篇(持续更新)

目录 本文分两篇&#xff0c;进阶篇点击&#xff1a;C#基础与进阶扩展合集-进阶篇 一、基础入门 Ⅰ 关键字 Ⅱ 特性 Ⅲ 常见异常 Ⅳ 基础扩展 1、哈希表 2、扩展方法 3、自定义集合与索引器 4、迭代器与分部类 5、yield return 6、注册表 7、不安全代码 8、方法…

MATLAB中cell函数的用法

cell用法 在MATLAB中&#xff0c;cell 是一种特殊的数据类型&#xff0c;用于存储不同大小和类型的数据。cell 数组是一种容器&#xff0c;每个元素可以包含任意类型的数据&#xff0c;包括数值、字符串、矩阵、甚至其他的 cell 数组。 以下是 cell 数组的基本语法和示例&…

gitblit自建git仓库

安装 java sudo apt-get update sudo apt-get install openjdk-8-jdk # 或者其它你喜欢的版本 验证&#xff1a; java -version 下载 gitblit https://github.com/gitblit-org/gitblit/releases 解压/usr/local tar -zxvf gitblit-1.9.3.tar.gz 修改配置文件 nano /usr/local/…

【React】useCallback 使用的说明

文章目录 useCallback的优缺点优点缺点JavaScript 的内联优化 使用场景 用了两年多的react&#xff0c;今天抽空写点小内容 useCallback的优缺点 缓存了每次渲染时候 inline callback的实例 优点 关键点&#xff1a;利用memoize减少无效的re-render&#xff0c;通常配合shouldC…