Spring Data Multi-store 实战:JPA 与 MongoDB 共存时仓库的严格自动分配机制
示例工程【免费下载链接】spring-data-examplesSpring Data Example Projects项目地址https://gitcode.com/gh_mirrors/sp/spring-data-examples点击查看免费下载本指南以 spring-data-examples 仓库中的multi-store示例为骨架讲解在一个应用内同时启用 Spring Data JPA 与 Spring Data MongoDB 两个模块时Spring Data 如何识别当前仓库接口到底该交给哪个存储模块这一核心问题。读完本文你将掌握多存储应用下仓库自动检测repository auto-detection的严格配置模式strict repository configuration mode、Entity/Document注解驱动的分配规则以及如何用测试验证仓库被正确分配给了对应的存储。背景为什么多存储应用需要更严格的仓库检测Spring Data 的仓库抽象允许开发者只写接口如CrudRepository而不写实现类。当应用只使用一个 Spring Data 模块时检测逻辑非常简单扫描到仓库接口就注册。但当应用同时引入多个 Spring Data 模块例如 JPA MongoDB时同一个仓库接口可能被多个模块都看着像自己该管的此时就需要一个明确的判定规则。正如 multi-store/README.md 开头所述This sample shows a project working with multiple Spring Data modules and how the repository auto-detection has become stricter with the Evans release train.也就是说从Evans版本系列Spring Data 的 release train 代号开始仓库自动检测行为变得更加严格一旦 Spring Data 检测到应用同时运行在多个 Spring Data 模块之上就会进入strict repository configuration mode严格仓库配置模式在此模式下只有能够被唯一分配给当前扫描模块的仓库接口才会被注册。示例工程结构一览multi-store模块本身是一个 Maven 子工程见根 pom.xml 中的modules列表其目录结构如下multi-store/ ├── pom.xml └── src/ ├── main/java/example/springdata/multistore/ │ ├── ApplicationConfiguration.java │ ├── customer/ (Address.java, Customer.java, CustomerRepository.java) │ └── shop/ (LineItem.java, Order.java, OrderRepository.java) └── test/java/example/springdata/multistore/ └── ApplicationConfigurationTest.java工程只有两个领域域store domaincustomer 域走 JPA关系型数据库测试时用 HSQLDB 内嵌库shop 域走 MongoDB测试时用 Testcontainers 启动真实 MongoDB 容器整个应用只需一个带SpringBootApplication的配置类即可完成装配ApplicationConfiguration.java 中没有任何显式的EnableJpaRepositories/EnableMongoRepositories声明——两个模块的仓库扫描全部由 Spring Boot 自动配置完成这正是仓库自动检测机制发挥作用的场景。两个存储域用注解标记归属严格模式下仓库接口的归属判断靠的是被管理的领域类型managed domain type上的存储专属注解。示例中恰好两个域各用了一个典型注解JPA 域Customer.java 用jakarta.persistence.Entity标注主键为Id GeneratedValue Long idData Entity public class Customer { private Id GeneratedValue Long id; private String firstname, lastname; private Address address; public Customer(String firstname, String lastname) { Assert.hasText(firstname, Firstname must not be null or empty!); Assert.hasText(lastname, Lastname must not be null or empty!); this.firstname firstname; this.lastname lastname; } // Required by JPA protected Customer() {} }其仓库接口 CustomerRepository.java 继承CrudRepositoryCustomer, Long完全交给 JPA 模块实现。MongoDB 域Order.java 用org.springframework.data.mongodb.core.mapping.Document标注Data RequiredArgsConstructor(onConstructor __(PersistenceCreator)) Document public class Order { private final String id; private final String customerId; private final Date orderDate; private final ListLineItem items; // ... }其仓库接口 OrderRepository.java 继承CrudRepositoryOrder, String。值得一提的细节是 Order.java 的类注释Note how we dont need any MongoDB mapping annotations asidis recognized as the id property by default.即 MongoDB 侧只需Documentid字段会被默认识别为文档主键无需额外映射注解。同理Address.java 用Embeddable作为 JPA 内嵌值对象嵌入Customer。核心机制严格仓库配置模式的运行日志multi-store模块的 ApplicationConfigurationTest.java 是一个SpringBootTest集成测试README 明确说明运行该测试即可在 DEBUG 日志中看到严格模式被激活的完整过程。原文档给出的日志如下… DEBUG … - Multiple Spring Data modules found, entering strict repository configuration mode! … … DEBUG … - Spring Data JPA - Could not safely identify store assignment for repository candidate interface example.springdata.multistore.shop.OrderRepository. … DEBUG … - Spring Data JPA - Registering repository: customerRepository - Interface: example.springdata.multistore.customer.CustomerRepository - Factory: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean … DEBUG … - Multiple Spring Data modules found, entering strict repository configuration mode! … … DEBUG … - Spring Data MongoDB - Could not safely identify store assignment for repository candidate interface example.springdata.multistore.customer.CustomerRepository. … DEBUG … - Spring Data MongoDB - Registering repository: orderRepository - Interface: example.springdata.multistore.shop.OrderRepository - Factory: org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean这段日志非常直观地展示了严格模式的两阶段判定触发Spring Data 发现应用同时存在多个 Spring Data 模块随即打印Multiple Spring Data modules found, entering strict repository configuration mode!并切换到严格模式。逐模块扫描与交叉排除当Spring Data JPA扫描时遇到OrderRepository其领域类型Order带有DocumentJPA 无法安全地确认这是自己的仓库于是打印Could not safely identify store assignment for repository candidate interface ... OrderRepository并跳过同时成功注册CustomerRepository领域类型带Entity工厂类为org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean。当Spring Data MongoDB扫描时对称地跳过CustomerRepository成功注册OrderRepository工厂类为org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean。这正是 README 所总结的默认判定规则By default this assignment is detected by inspecting the managed domain type for store specific annotations (e.g.Entityfor JPA orDocumentfor MongoDB).也就是说Could not safely identify store assignment 并不是报错而是严格模式下的正常现象——各模块在交叉扫描到不属于自己的仓库接口时主动让位从而保证每个仓库接口最终被唯一分配到一个存储模块避免同一个接口被两个模块重复实例化造成歧义。用断言验证仓库归属Repositories API严格模式是否真的把仓库分配给了正确的存储测试用RepositoriesAPI 给出了可验证的结论。核心断言位于 ApplicationConfigurationTest.javaTest void repositoriesAreAssignedToAppropriateStores() { var repositories new Repositories(context); assertThat(repositories.getEntityInformationFor(Customer.class)).isInstanceOf(JpaEntityInformation.class); assertThat(repositories.getEntityInformationFor(Order.class)).isInstanceOf(MongoEntityInformation.class); }这里通过org.springframework.data.repository.support.Repositories从ApplicationContext中检索每个领域类型对应的EntityInformationCustomer的实体信息是org.springframework.data.jpa.repository.support.JpaEntityInformationJPA 侧Order的实体信息是org.springframework.data.mongodb.repository.query.MongoEntityInformationMongoDB 侧。由此可以从运行时证据上确认仓库自动检测确实把两个仓库接口分别分配给了 JPA 与 MongoDB 两个模块。该测试还演示了多存储应用测试环境的搭建——通过TestConfiguration配合 Testcontainers 启动 MongoDB 容器TestConfiguration static class Infrastructure { Bean ServiceConnection MongoDBContainer mongoDBContainer() { return new MongoDBContainer(DockerImageName.parse(mongodb/mongodb-community-server)); } }ServiceConnection是 Spring Boot 的测试特性容器启动后其连接信息会自动配置到应用的 MongoDB 连接中测试类无需手写任何连接参数。JPA 侧则使用 HSQLDB 内嵌数据库test 作用域因此运行该测试的前提是本机安装有 Docker用于启动 MongoDB 容器。依赖配置同时引入两个 Starter多存储应用的依赖装配体现在 multi-store/pom.xml 中核心依赖只有两个 Starterdependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-mongodb/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency配套的测试依赖包括org.hsqldb:hsqldbtest 作用域JPA 侧内嵌库与org.testcontainers:testcontainers-mongodbtest 作用域MongoDB 侧容器。整个工程继承仓库根 pom.xml当前基于 Spring Boot 4.0.4、Java 25 编译级别因此两个 Starter 的版本号由父 POM 统一管理无需显式书写。运行方式在仓库根目录执行./mvnw -pl multi-store test或在multi-store目录下执行../mvnw test即可运行ApplicationConfigurationTest并观察到上文所述的严格模式 DEBUG 日志。延伸阅读Spring Data REST 视角下的多存储实践仓库中还提供了另一个同主题示例rest/multi-store见根 README.adoc 中 A sample REST web-service based on both Spring Data JPA and Spring Data MongoDB 的说明它把同样的 JPA MongoDB 双存储组合放在了 Spring Data REST 场景下Person.java 用Entity标注走 JPAH2 内嵌库Treasure.java 用Document标注走 MongoDBApplication.java 同样是极简的SpringBootApplicationApplicationIntegrationTests.java 中直接Autowired注入PersonRepository与TreasureRepository同时向两个存储写入数据并遍历读取从使用层面演示了双存储仓库的开箱即用。该示例的 pom.xml 依赖模式与multi-store一致JPA MongoDB 两个 Starter、H2、testcontainers-mongodb可作为把多存储能力暴露为 REST 服务时的参考模板。实践要点小结严格模式由多个 Spring Data 模块共存自动触发无需任何显式配置触发后日志中会出现Multiple Spring Data modules found, entering strict repository configuration mode!。仓库归属默认由领域类型上的存储专属注解决定JPA 看EntityMongoDB 看Document。若领域类型没有任何可识别的存储注解例如纯 POJO 被多个模块扫描到就会出现 Could not safely identify store assignment 并被跳过——这是设计行为而非故障。保持领域类型与仓库一一对应确保每个仓库接口的领域类型带有且仅带有目标存储的注解是让自动检测稳定工作的前提。用RepositoriesAPI 做运行时验证像ApplicationConfigurationTest那样断言EntityInformation的具体实现类可以在 CI 中持续保证仓库分配的 correctness。测试环境依赖 DockerMongoDB 侧通过 Testcontainers 容器提供真实存储运行集成测试前需确保 Docker 可用。赞分享示例工程【免费下载链接】spring-data-examplesSpring Data Example Projects项目地址https://gitcode.com/gh_mirrors/sp/spring-data-examples点击查看免费下载相关推荐Spring Data多数据源配置JPA与MongoDB混合存储终极指南 Spring Data多数据源配置JPA与MongoDB混合存储终极指南 在现代企业级应用开发中如何高效配置和管理 Spring Data多数据源 成示例工程Noname 移动端Capacitor Android SAF构建与文件系统覆盖层实战指南Noname 移动端Capacitor Android SAF构建与文件系统覆盖层实战指南 Noname无名杀的移动端采用 Capacitor 封装示例工程Spring Data JPA 多数据源实战手动装配 CustomerConfig 与 OrderConfig 隔离两个独立数据库Spring Data JPA 多数据源实战手动装配 CustomerConfig 与 OrderConfig 隔离两个独立数据库 本指南以 spring d示例工程上一篇CangjieMagic 模型管理指南ModelConfig、ModelManager 与 ModelUtils 实战解析下一篇【亲测免费】 开源项目推荐Open Source Report Card (OSRC)创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

QGroundControl GeoMap 引擎深度解析:基于 Qt Quick 3D 的 2D/3D 高程地形地图实现

QGroundControl GeoMap 引擎深度解析:基于 Qt Quick 3D 的 2D/3D 高程地形地图实现

无人机智能硬件 【免费下载链接】qgroundcontrol Cross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows) 项目地址: https://gitcode.com/gh_mirrors/qg/qgroundcontrol 点击查看 免费下载 导读 GeoMap 是 QGroundControl&am…

2026/10/15 1:56:09 阅读更多 →
蓝鲸配置平台 bk-cmdb 开源社区参与指南:从 Issue 提报到 Pull Request 合并的完整贡献流程

蓝鲸配置平台 bk-cmdb 开源社区参与指南:从 Issue 提报到 Pull Request 合并的完整贡献流程

后端企业应用运维 【免费下载链接】bk-cmdb 蓝鲸智云配置平台(BlueKing CMDB) 项目地址: https://gitcode.com/gh_mirrors/bk/bk-cmdb 点击查看 免费下载 蓝鲸配置平台(BlueKing CMDB,bk-cmdb)是蓝鲸智云开源的一款企业级配置管理…

2026/10/15 1:56:09 阅读更多 →
仓颉 cangjie_runtime std.convert 转换接口详解:Formattable、Parsable 与 RadixConvertible

仓颉 cangjie_runtime std.convert 转换接口详解:Formattable、Parsable 与 RadixConvertible

编程语言语言运行时标准库垃圾回收并发编程 【免费下载链接】cangjie_runtime 仓颉编程语言运行时与标准库。 项目地址: https://gitcode.com/Cangjie/cangjie_runtime 点击查看 免费下载 本文围绕仓颉标准库 std.convert 包中的三个核心接口展开:Forma…

2026/10/15 1:55:08 阅读更多 →

最新新闻

Americhem在中国苏州启用全新洁净配混设施

Americhem在中国苏州启用全新洁净配混设施

全球定制聚合物解决方案领导者Americhem于9月28日举行了其位于苏州的全新洁净配混设施启用仪式。此项投资进一步提升了Americhem服务中国、亚太地区以及在该区域开展生产制造业务的全球客户的能力。 该设施专为满足严苛医疗器械应用所需的ISO 13485和cGMP要求而设计&#xff0c…

2026/10/15 2:28:21 阅读更多 →
如何降低文献综述的AI检测率:策略与技巧

如何降低文献综述的AI检测率:策略与技巧

1. 文献综述写作中的AI检测率问题剖析最近在学术圈里有个现象特别有意思:不少研究生朋友在提交论文查重时,发现文献综述部分的AI检测率总是居高不下。上周就遇到个案例,某高校硕士生小张的文献综述AI率竟然高达38%,远超过学院规定…

2026/10/15 2:28:21 阅读更多 →
青岛栈桥12家老字号美食攻略与避坑指南

青岛栈桥12家老字号美食攻略与避坑指南

1. 青岛栈桥美食地图:本地人私藏的12家老字号青岛栈桥作为城市地标,周边隐藏着许多经营数十年的地道美食。这些店铺往往没有华丽的装潢,却用最朴实的味道征服了几代食客的味蕾。我作为在青岛生活15年的"老饕",今天要分享…

2026/10/15 2:28:21 阅读更多 →
AI辅助科研:驱动科研创新升级的新动能与实践路径

AI辅助科研:驱动科研创新升级的新动能与实践路径

外文文献“白嫖”与高效阅读全攻略 宝子们,是不是一提到下载外文文献就头大? 想找的文献要么全网搜不到,要么下载流程复杂到让人原地爆炸。好不容易在某个小网站找到了资源,又担心版权问题不敢点,更别说有些平台动辄几…

2026/10/15 2:28:21 阅读更多 →
毕业设计-基于微信小程序的广州旅游服务系统

毕业设计-基于微信小程序的广州旅游服务系统

第1章 绪论:背景(政策/市场/技术/广州产业四方面) 国内外现状 目的意义(提升体验/促进产业/创新模式/智慧城市) 第2章 技术介绍:B/S、Uni-app、MySQL、Django、Vue 第3章 分析与设计:用户/系统…

2026/10/15 2:28:21 阅读更多 →
程序员英语词汇宝典词条精讲:exclamation mark(感叹号 `!`)——发音、词义与编程实战用法

程序员英语词汇宝典词条精讲:exclamation mark(感叹号 `!`)——发音、词义与编程实战用法

教程 【免费下载链接】most-frequent-technology-english-words 程序员工作中常见的英语词汇 项目地址: https://gitcode.com/gh_mirrors/mo/most-frequent-technology-english-words 点击查看 免费下载 本文以开源仓库 most-frequent-technology-english-words&am…

2026/10/15 2:27:21 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →