# 迁到 MongoDB 以后 Hibernate 那套接不上，Spring Data 该管哪一段？

**URL:** <https://www.shiqidu.com/t/topic/1896>\
**Category:** 开发调优\
**Tags:** MongoDB, Java, 数据库\
**Created:** [2026 年11 月 2 日 07:19 UTC](https://www.shiqidu.com/t/topic/1896 "2026-11-02T07:19:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![shiqidu\_editor](https://www.shiqidu.com/user_avatar/www.shiqidu.com/shiqidu_editor/32/528_2.png) [@shiqidu\_editor](https://www.shiqidu.com/u/shiqidu_editor)\
发布日期： [2026 年11 月 2 日 07:19 UTC](https://www.shiqidu.com/t/topic/1896/1 "2026-11-02T07:19:43Z")

</div>

集合名、字段名都迁完了，Java 服务这边还想继续用 Session、懒加载、一对多级联。编译器一报，才发现那些 API 在 Mongo 这边对不上号。文档库跟关系 ORM 本来就不是同一套语义。Mongo 这边 Java 生态里更常见的入口是 Spring Data MongoDB。

## 文档库别硬套关系 Session

关系 ORM 围着表、外键、Session / 一级缓存、脏检查、懒加载代理转。MongoDB 存的是文档（和可选的引用），没有「按外键自动拼实体图」那一套一等公民。事务、锁、关联加载的默认假设也不一样。把 `@OneToMany`、`Session.get`、`LazyInitializationException` 心智原样搬过去，只会到处找不存在的 API。

《[Spring Data MongoDB 参考文档](https://docs.spring.io/spring-data/mongodb/reference/index.html)》开篇就定位：用模板类做核心 API，再用轻量 Repository 风格访问，编程模型和 Spring 其它 Data 模块对齐。功能概览页列了配置与驱动连接、`MongoTemplate`、异常翻译、对象映射、注解元数据、生命周期事件、Query/Criteria DSL、Repository 自动实现、多文档事务、Change Streams、GridFS、地理与向量检索等——管的是「文档怎么连、怎么映、怎么查、怎么订阅读」，不是 Hibernate Session 的替身。

命名上也尽量贴 MongoDB Java 驱动，方便把已有驱动经验映射到 Spring API，而不是再学一套「Mongo 版 JPA」。

## Template 和 Repository 各管什么

按[功能说明](https://docs.spring.io/spring-data/mongodb/reference/mongodb.html)的分工：

- 大多数增删改查、按条件更新、计数之类，优先 Repository 或 `MongoTemplate`。两者都走同一套映射。
- 需要贴近驱动、拿 `MongoDatabase`、做不太适合派生查询的操作时，用 Template 的回调往下钻。
- 映射把文档和 POJO 对上。复杂聚合、批量更新往往直接写 Query / Aggregation，别指望 Criteria 自动生成跟 SQL 一样的 join。
- GridFS 适合大文件。Change Streams 适合「集合有变更就推下来」。多文档事务、会话在独立章节，迁库时按需打开，别假定「开了 Spring 事务注解就和 InnoDB 行为一模一样」。

版本从 2.x 升到 3.x、4.x、5.x 时，驱动与映射的破坏性变更要看文档里的升级说明。参考站首页有 What’s New / Upgrade Notes 入口。别在生产上跳大版本却只改依赖号。

## 迁库时人容易卡的几处

- 原来靠外键级联删的，到文档模型要重新想：内嵌、手工引用、还是应用层补偿。内嵌读路径简单，文档变大、并发更新同一文档会变疼。只存引用则每次拼装多一次查询。
- 「懒加载一个关联集合」在 Mongo 里常常变成另一次查询或一次聚合，显式写出来更安全，也少在调试时猜「这次发了几条命令」。
- 事务边界：单文档原子性是常态。跨文档事务有成本，也不是每个部署都开。能靠单文档设计收掉的一致性，就别先上多文档事务。
- 查询直觉：没有固定 schema 不等于没有索引规划。字段名一改，旧索引和旧查询会一起哑火。派生查询方法名和字段对不上时，宁可写成显式 `@Query` / Criteria，少靠魔法方法名硬猜。
- 异常类型：Spring Data 会把驱动异常翻成 Spring 的 DataAccessException 体系，上层 catch 策略要跟着改，别再只认 Hibernate 那串异常名。

这篇不给出谁更快的数字，也没有「ORM 淘汰」之类的口号。关系库继续用 Hibernate / JPA 很常见。库已经迁到 Mongo 时，Java 侧应接的是 Spring Data MongoDB 的 Template / Repository / 映射与流式能力，而不是再找一个「Mongo 版 Session」。历史上还有过面向文档库的 ORM 实验，多数项目最终还是回到官方驱动或 Spring Data 这条主线，正文不展开那些已停更的支线。

你们迁完以后，是 Repository 派生日志查询为主，还是大量 Aggregation 写在 Template 里？有没有人坚持再套一层类 Hibernate 的封装，后来又拆掉的？
