spring-projects / spring-projects/spring-data-mongodb

Allow to understand MappingInstantiationException [DATAMONGO-2511]

Open
#3,365 0 comments 0 reactions 1 assignee View on GitHub

@christophstrobl is already working on this.

Since Dec 30, 2020.

type: enhancement
Dominant language
Java
Stars
1.7k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

Piotr Kubowicz opened DATAMONGO-2511 and commented

When you call findAll() on a Mongo-based repository and one of the documents is outdated, you receive a MappingInstantiationException that shows details of contructor call that failed.

This is not enough information to diagnose the problem. You are not able to find out which particular document is malformed.

org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate Foo using constructor fun <init>(kotlin.String, kotlin.Boolean, kotlin.collections.List<kotlin.String>, kotlin.Int, java.time.Instant): Foo with arguments 5e9047feb66b876dd06a518b,null,null,null,null
	at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:228)
	at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:322)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:295)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:226)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:222)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:95)
	at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3162)
	at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2799)
	at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2532)
	at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2515)
	at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:876)
	at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:380)
	at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:204)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:371)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:99)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy140.findAll(Unknown Source)

I was able to work around this by creating a wrapper class around MappingMongoConverter and making Spring Boot use it:

@Bean
fun reactiveMongoTemplate(reactiveMongoDatabaseFactory: ReactiveMongoDatabaseFactory, converter: MongoConverter) =
    ReactiveMongoTemplate(reactiveMongoDatabaseFactory, DiagnosingMongoConverter(converter))

@Bean
fun mongoTemplate(mongoDbFactory: MongoDbFactory, converter: MongoConverter) =
    MongoTemplate(mongoDbFactory, DiagnosingMongoConverter(converter))

but I think this should be a core functionality. The idea is to modify MappingMongoConverter.read() and try to retrieve ObjectId from _id field of the Document and report it in the exception.

I can provide a pull request


Affects: 2.2.6 (Moore SR6)

Referenced from: pull request https://github.com/spring-projects/spring-data-mongodb/pull/860

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.