You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MongoDB通过ID查询文档报错:参数无名称

Spring MongoDB通过ID查询时MappingException异常解决思路

问题场景

调用以下代码通过ID查询Resource文档:

Optional<Resource> resource = resourceMongoRepository.findById("65df60edbd43c107768b6191");

抛出异常:

Caused by: org.springframework.data.mapping.MappingException: Parameter org.springframework.data.mapping.Parameter@c946e82b does not have a name

Repository定义:

public interface ResourceMongoRespository
    extends MongoRepository<Resource, String> {

}

Mongo查询日志:

DEBUG 189104 --- [tContainer#0-24] o.s.data.mongodb.core.MongoTemplate : findOne using query: { "_id" : "65df60edbd43c107768b6191"} fields: Document{{}} for class: class net.gencat.transversal.espaidoc.infrastructure.model.Resource in collection: resource

mongosh中执行查询正常返回数据:

test> db.resource.find({"_id" : ObjectId("65df60edbd43c107768b6191")});
[
  {
    _id: ObjectId('65df60edbd43c107768b6191'),
    resourceId: Binary.createFromBase64('MkpJzQuAUBwhFCqfXjT4ow==', 3),
    resourceLocation: { location: '1c50800b-cd49-4a32-a3f8-345e9f2a1421', type: 'S3' },
    documentState: 'PENDING',
    _class: 'net.gencat.transversal.espaidoc.infrastructure.model.Resource'
  }
]

完整异常栈:

Caused by: org.springframework.data.mapping.MappingException: Parameter org.springframework.data.mapping.Parameter@7627f000 does not have a name
        at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:61) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:301) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:273) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:519) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:487) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter$DefaultConversionContext.convert(MappingMongoConverter.java:2366) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter$ConversionContext.convert(MappingMongoConverter.java:2175) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1941) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:626) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:544) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:522) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:487) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:423) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:419) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:119) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3278) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2874) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2536) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:817) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findById(SimpleMongoRepository.java:127) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70) ~[spring-data-commons-3.2.2.jar:3.2.2]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.data.mongodb.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:158) ~[spring-data-mongodb-4.2.2.jar:4.2.2]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar:6.1.3]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220) ~[spring-aop-6.1.3.jar:6.1.3]
        at jdk.proxy2/jdk.proxy2.$Proxy57.findById(Unknown Source) ~[na:na]
        at net.gencat.transversal.espaidoc.infrastructure.repository.DocumentPersistenceOperations.get(DocumentPersistenceOperations.java:50) ~[infrastructure-0.0.1-SNAPSHOT.jar:na]
        at net.gencat.transversal.espaidoc.application.document.pushed.PushedDocumentUseCase.consolidate(PushedDocumentUseCase.java:14) ~[application-0.0.1-SNAPSHOT.jar:na]
        at net.gencat.transversal.espaidoc.presentation.backoffice.rest.sqs.SQSS3CreatedNotificationService.listen(SQSS3CreatedNotificationService.java:45) ~[classes/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:169) ~[spring-messaging-6.1.3.jar:6.1.3]

解决思路

这个异常的核心原因是Spring Data在实例化Resource实体类时,无法识别构造方法的参数名称,导致映射失败。以下是针对性的解决方案:

  • 检查Resource实体类的构造方法

    1. 如果实体类使用了带参数的构造方法,确保编译时保留参数名称:
      • Maven项目:在pom.xml的maven-compiler-plugin中添加<parameters>true</parameters>配置,让编译器生成参数名称信息。
      • Gradle项目:在build.gradle中设置compileJava.options.parameters = true。
    2. 给构造方法添加@PersistenceConstructor注解,明确指定该构造方法用于Spring Data的实体实例化,示例:
      public class Resource {
          @PersistenceConstructor
          public Resource(String id, Binary resourceId, ResourceLocation resourceLocation, String documentState) {
              // 构造方法逻辑
          }
      }
      
  • 改用无参构造方法+Setter模式
    如果不需要带参数的构造方法,给Resource类添加无参构造方法,并为所有字段提供Setter方法,让Spring Data通过Setter完成属性注入。

  • 检查嵌套对象的构造逻辑
    从查询结果看Resource包含resourceLocation嵌套对象,需确保该嵌套类同样满足构造方法要求:要么有保留参数名的带参构造+@PersistenceConstructor,要么有无参构造+Setter。

  • 验证ID类型匹配
    日志中查询用字符串ID,但Mongo存储的是ObjectId。检查Resource类的ID字段定义:如果是String类型,Spring Data会自动转换;如果是ObjectId类型,需确保查询时传入ObjectId实例,或配置正确的类型转换。

内容的提问来源于stack exchange,提问作者Jordi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:35:54