就在昨晚,我满怀斗志的准备开始写项目,在我创建一个Spring Boot 3.3.2的多模块父工程,需要引入mybatis-plus-join
以实现联表查询时,我遇到了很奇怪的的情况,由于我至今也无法确定到底是什么导致的,所以我记录下我操作的全过程,希望能和大家交流探讨。
第一阶段:初识报错,发现环境问题
我首先配置好了父工程的pom.xml
,其中包含了mybatis-plus-join
的依赖管理:
xml
<properties> <mybatis-plus-join.version>1.5.2</mybatis-plus-join.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-join-boot-starter</artifactId> <version>${mybatis-plus-join.version}</version> </dependency> </dependencies> </dependencyManagement>
项目创建后,所有依赖都报错了。经过排查,我发现这是因为使用的是新JDK 21,但IDEA中Maven的Runner配置仍使用的是旧版本JDK。修正了这个环境配置后,其他依赖都正常了,但唯独mybatis-plus-join
依然标红。
第二阶段:深入排查,发现坐标错误
面对持续的标红,我开始了深入排查。首先发现了依赖坐标的错误:mybatis-plus-join
是一个第三方扩展,正确的groupId
应该是com.github.yulichang
,而我配置的是com.baomidou
。
xml
<!-- 错误的配置 --> <dependency> <groupId>com.baomidou</groupId> <!-- 错误的groupId --> <artifactId>mybatis-plus-join-boot-starter</artifactId> <version>1.5.2</version> </dependency> <!-- 正确的配置 --> <dependency> <groupId>com.github.yulichang</groupId> <!-- 正确的groupId --> <artifactId>mybatis-plus-join-boot-starter</artifactId> <version>1.5.2</version> </dependency>
我立即将groupId
修正为com.github.yulichang
,但令人困惑的是,依赖依然标红。
第三阶段:探究根源,发现本地仓库异常
又经过一番排查后我几乎尝试了所有常规手段:mvn clean compile -U
、Invalidate Caches / Restart
,都无济于事。就在我崩溃之时突然想到坐标已经正确但依然标红且没有报错,我决定查看本地Maven仓库(~/.m2/repository
)。发现仓库里根本没有com/github/yulichang
这个目录,这意味着依赖确实没有被下载。
这时我才意识到:在父工程的<dependencyManagement>
中声明版本,只是给子模块制定"规则",并没有真正引入依赖。需要在父工程的<dependencies>
中实际引入:
xml
<dependencies> <dependency> <groupId>com.github.yulichang</groupId> <artifactId>mybatis-plus-join-boot-starter</artifactId> </dependency> </dependencies>
这样操作后,依赖终于成功下载,标红问题解决了。但是这又引出一个问题,为何只是给子模块制定"规则",并没有真正引入依赖,idea会标红呢?于是我开始了测试
第四阶段:诡异的现象
问题解决后,我出于测试目的:
-
从
<dependencies>
中删除了引入语句 -
手动删除了本地仓库中的
com/github/yulichang
目录
令人惊讶的是:IDEA这次没有再标红! 只有当我再次故意将groupId
改回错误的com.baomidou
时,标红才重新出现。这就很奇怪了一样的情况,但当初遇到的令我头痛的标红如今消失不见了,所以我再次记录下了这件事。
下面是我询问deepseek后得到的可能的几种原因:
IDE 为了提升性能,会对项目的依赖解析结果进行缓存和持久化。我认为最可能的原因是:在你成功编译后,IDEA 将“com.github.yulichang:mybatis-plus-join-boot-starter:1.5.2
是一个可解析的有效依赖”这一状态记忆了下来,即使你后来删除了本地文件,IDEA 在某种状态下依然信赖这个记忆。
以下是几种具体的可能性,它们很可能同时起作用:
1. IDEA 的项目元数据(.idea
目录下的文件)残留
这是最可能的原因。当你成功编译后,IDEA 会在项目目录下的 .idea
文件夹中(例如在 libraries
或 workspace.xml
文件里)记录依赖解析成功的状态。
-
发生了什么:你删除了本地仓库的
.jar
包,但没有删除项目中的.idea
目录。当你重新打开项目时,IDEA 读取了这些元数据文件,发现其中记录着“此依赖已成功解析”,因此它可能选择相信这个记录,而不是立即去检查本地仓库是否真的存在这个文件。 -
为什么改回错误 GroupId 会报错:因为当你改回
com.baomidou
时,这个坐标在 IDEA 的元数据中没有“成功解析”的记录,或者这个记录是无效的,所以 IDEA 会触发一次全新的、严格的依赖解析检查,从而立即报错。
2. Maven 元数据文件 (_remote.repositories
, *.lastUpdated
) 的影响
Maven 在下载依赖时,不仅会留下 .jar
文件,还会生成一些元数据文件。
-
发生了什么:当你手动删除依赖时,可能只删除了
.jar
和.pom
文件,但残留了_remote.repositories
等文件。这些文件的存在可能会给 IDEA 一个信号:“这个依赖之前是从哪个仓库成功下载过的,只是文件暂时不见了”。IDEA 可能会据此认为这是一个“可恢复”的状态,而非一个“绝对错误”的状态,因此降低了报错的优先级。
3. IDEA 的“静默”后台自动重试机制
IDEA 的行为有时比我们想象的更“智能”。
-
发生了什么:在你删除依赖并重新打开项目后,IDEA 可能在后台自动尝试重新解析依赖。这个过程可能不是瞬时的。在解析出结果之前,IDEA 可能选择暂时显示上一次已知的状态(即“成功”状态),而不是直接报错。你可能正是在这个“静默期”观察的项目,所以没有看到报错。如果等待足够长的时间,或者触发某些操作(如执行
mvn compile
),它最终可能会重新报错。
由于我在报错后就多次询问deepseek,它多次回答相同,甚至有时前后回答互相矛盾,所以我现在也没有办法完全相信它的这番解释了,虽然我也很想知道真相是什么,但复现的话太过麻烦,且对于实际技术并无太大提升,和idea的相关原理也是无从而知,所以只希望下次也有人遇到和我一样的状况,可以看到我的文章,找到解决方法。