Spring Boot整合MySQL与MongoDB时mongoTemplate依赖异常求助
Spring Boot集成MySQL+MongoDB启动失败解决方案
问题现象
启动应用时抛出UnsatisfiedDependencyException,提示无法解析mongoTemplate bean以设置mongoOperations,错误栈根因为Java模块权限限制:
java.lang.reflect.InaccessibleObjectException: Unable to make field private java.util.Date java.security.Timestamp.timestamp accessible: module java.base does not "opens java.security" to unnamed module @3c9754d8
可行解决方案
1. 添加JVM启动参数开放模块权限
Java 9+的模块系统禁止未命名模块反射访问java.security包,需在启动时添加以下VM参数:
--add-opens java.base/java.security=ALL-UNNAMED
- IDE运行:在Run Configuration的VM Options中添加该参数
- 打包运行:执行
java --add-opens java.base/java.security=ALL-UNNAMED -jar your-app.jar
2. 清理JJWT依赖冲突
Gradle依赖中同时引入了JJWT的0.11.5和0.9.1两个版本,存在版本冲突,删除旧版本依赖:
修改build.gradle的dependencies块,移除:
implementation 'io.jsonwebtoken:jjwt:0.9.1' // JWT library
保留0.11.5版本的三个JJWT依赖即可。
3. 移除不必要的Jython依赖
jython-slim:2.7.3为Python兼容库,若项目未使用该库,直接删除:
implementation group: 'org.python', name: 'jython-slim', version: '2.7.3'
该库可能引入与Java 21模块系统不兼容的旧类,触发反射权限问题。
4. 验证MongoDB配置与服务状态
- 确认
spring.data.mongodb.uri配置正确:mongodb://localhost:27017/ - 本地MongoDB服务已启动在27017端口
- 数据库
mongoInventory会自动创建,无需提前手动创建
验证步骤
- 执行
./gradlew clean build --refresh-dependencies清理缓存并重新构建 - 先仅保留MongoDB相关依赖与配置,启动验证是否正常
- 逐步添加MySQL、Security等其他依赖,排查是否有新的冲突
附用户环境信息
应用配置
spring.application.name=Inventory spring.datasource.url=jdbc:mysql://localhost:3306/inventory spring.datasource.username=root spring.datasource.password= spring.data.mongodb.uri=mongodb://localhost:27017/ spring.data.mongodb.database=mongoInventory spring.jpa.show-sql=true spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect logging.level.org.springframework.data.mongodb=DEBUG logging.level.org.springframework=DEBUG server.error.include-exception=true server.error.include-stacktrace=always spring.main.allow-circular-references=true logging.level.org.hibernate=TRACE
Gradle依赖(原始)
plugins { id 'java' id 'org.springframework.boot' version '3.2.5' id 'io.spring.dependency-management' version '1.1.4' } group = 'com.InventoryCHU' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '21' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' implementation group: 'org.python', name: 'jython-slim', version: '2.7.3' compileOnly 'org.projectlombok:lombok' implementation 'com.h2database:h2' implementation 'io.jsonwebtoken:jjwt:0.9.1' // JWT library runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
核心代码示例
MongoDB Repository
package com.InventoryCHU.Inventory.Repository; import com.InventoryCHU.Inventory.Models.BreakDown; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.Optional; public interface BreakDownRepository extends MongoRepository<BreakDown , String> { Optional<BreakDown> findBreakDownByItemId(String item); }
Service层
package com.InventoryCHU.Inventory.Services; import com.InventoryCHU.Inventory.Models.BreakDown; import com.InventoryCHU.Inventory.Repository.BreakDownRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class BreakDownService { @Autowired BreakDownRepository breakDownRepository; public List<BreakDown> getAllBreakDowns(){ return breakDownRepository.findAll(); } public Optional<BreakDown> getBreakDownById(String Id){ return breakDownRepository.findById(Id); } public BreakDown createBreakDown(BreakDown breakDown){ return breakDownRepository.save(breakDown); } public void deleteBreakDown(String Id){ breakDownRepository.deleteById(Id); } public Optional<BreakDown> findBreakDownByItemId(String productId){ return breakDownRepository.findBreakDownByItemId(productId); } }
Controller层
package com.InventoryCHU.Inventory.Controllers; import com.InventoryCHU.Inventory.Models.BreakDown; import com.InventoryCHU.Inventory.Services.BreakDownService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Optional; @RestController @RequestMapping("/api/breakdown") public class BreakDownController { @Autowired BreakDownService breakDownService; @GetMapping public ResponseEntity<List<BreakDown>> getAllBreakDowns() { List<BreakDown> breakDowns = breakDownService.getAllBreakDowns(); return ResponseEntity.ok(breakDowns); } @GetMapping("/{id}") public ResponseEntity<BreakDown> getBreakDownById(@PathVariable String id) { Optional<BreakDown> breakDown = breakDownService.getBreakDownById(id); return breakDown.map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @GetMapping("/product-{id}") public ResponseEntity<BreakDown> getBreakDownByUserId(@PathVariable("id") String productId){ Optional<BreakDown> breakDown = breakDownService.findBreakDownByItemId(productId); return breakDown.map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @PostMapping(consumes = "application/json", produces = "application/json") public ResponseEntity<BreakDown> createBreakDown(@RequestBody BreakDown breakDown) { BreakDown createdBreakDown = breakDownService.createBreakDown(breakDown); return ResponseEntity.status(HttpStatus.CREATED).body(createdBreakDown); } @DeleteMapping("/delete/{id}") public ResponseEntity<Void> deleteBreakDown(@PathVariable String id) { breakDownService.deleteBreakDown(id); return ResponseEntity.noContent().build(); } }
完整错误栈
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'breakDownController': Unsatisfied dependency expressed through field 'breakDownService': Error creating bean with name 'breakDownService': Unsatisfied dependency expressed through field 'breakDownRepository': Error creating bean with name 'breakDownRepository' defined in com.InventoryCHU.Inventory.Repository.BreakDownRepository defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations' Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'breakDownService': Unsatisfied dependency expressed through field 'breakDownRepository': Error creating bean with name 'breakDownRepository' defined in com.InventoryCHU.Inventory.Repository.BreakDownRepository defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations' Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'breakDownRepository' defined in com.InventoryCHU.Inventory.Repository.BreakDownRepository defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations' Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 1: Error creating bean with name 'mappingMongoConverter' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mappingMongoConverter' parameter 1: Error creating bean with name 'mongoMappingContext' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.class]: Unable to make field private java.util.Date java.security.Timestamp.timestamp accessible: module java.base does not "opens java.security" to unnamed module @3c9754d8 Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mappingMongoConverter' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mappingMongoConverter' parameter 1: Error creating bean with name 'mongoMappingContext' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.class]: Unable to make field private java.util.Date java.security.Timestamp.timestamp accessible: module java.base does not "opens java.security" to unnamed module @3c9754d8 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoMappingContext' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.class]: Unable to make field private java.util.Date java.security.Timestamp.timestamp accessible: module java.base does not "opens java.security" to unnamed module @3c9754d8 Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.util.Date java.security.Timestamp.timestamp accessible: module java.base does not "opens java.security" to unnamed module @3c9754d8
内容的提问来源于stack exchange,提问作者Youssef Elhejjioui
相关产品推荐
相关产品推荐

