Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoTemplate.findAndReplace throws Couldn't find PersistentEntity for type class org.bson.Document! #4061

Closed
yatw opened this issue May 20, 2022 · 1 comment
Labels
type: documentation A documentation update

Comments

@yatw
Copy link

yatw commented May 20, 2022

Attempting to do data migration and rename fields within nested array. But since $rename doesn't work. I am editing the document in json directly and use findAndReplace().

   /**
     * May 18, 2022
     * 1. Scenario, add a field schema_version and set to 1
     * 2. Action, add a field kgCO2eSavings
     */
    @Override
    public void migrate_v0Tov1(String scenarioId){
        Query query = new Query(Criteria.where("_id").is(scenarioId));
        mongoTemplate.executeQuery(query, "scenario", document -> {
            String jsonStr = document.toJson();
            JsonObject scenario = JsonParser.parseString(jsonStr).getAsJsonObject();
            scenario.addProperty("schema_version", "1");

            JsonArray buildingScenarios = scenario.getAsJsonArray("buildingScenarios");
            for (JsonElement buildingScenariosElement : buildingScenarios) {
                JsonObject buildingScenario = buildingScenariosElement.getAsJsonObject();
                JsonArray actions = buildingScenario.getAsJsonArray("actions");
                for (JsonElement actionElement : actions) {
                    JsonObject action = actionElement.getAsJsonObject();
                    JsonPrimitive capRateP = action.getAsJsonPrimitive("capRate");
                    action.add("kgCO2eSavings", JsonNull.INSTANCE);
                }
            }
            Document newDoc = Document.parse(scenario.toString());
            mongoTemplate.findAndReplace(query, newDoc); // <- exception here
        });
    }

}

If I am using MongoOperations.findAndReplace() without collectionName
Screen Shot 2022-05-20 at 11 03 25

Throw this exception

org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class org.bson.Document!
        at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:79)
        at org.springframework.data.mongodb.core.EntityOperations.determineCollectionName(EntityOperations.java:141)
        at org.springframework.data.mongodb.core.MongoTemplate.getCollectionName(MongoTemplate.java:433)
        at org.springframework.data.mongodb.core.MongoOperations.findAndReplace(MongoOperations.java:1016)
        at org.springframework.data.mongodb.core.MongoOperations.findAndReplace(MongoOperations.java:975)
        at com.xyz.projectnamescenario.scenarioDAO.dataMigration.CustomScenarioRepositoryImpl.lambda$migrate_v0Tov1$0(CustomScenarioRepositoryImpl.java:88)
        at <unknown class>.processDocument(Unknown Source)
        at org.springframework.data.mongodb.core.MongoTemplate.executeQueryInternal(MongoTemplate.java:2854)
        at org.springframework.data.mongodb.core.MongoTemplate.executeQuery(MongoTemplate.java:514)
        at org.springframework.data.mongodb.core.MongoTemplate.executeQuery(MongoTemplate.java:484)
        at com.xyz.projectnamescenario.scenarioDAO.dataMigration.CustomScenarioRepositoryImpl.migrate_v0Tov1(CustomScenarioRepositoryImpl.java:60)
        at com.xyz.projectnamescenario.scenarioDAO.dataMigration.CustomScenarioRepositoryImpl.handleMigration(CustomScenarioRepositoryImpl.java:45)
        at com.xyz.projectnamescenario.scenarioDAO.dataMigration.CustomScenarioRepositoryImpl$$FastClassBySpringCGLIB$$852e4f16.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
        at com.xyz.projectnamescenario.scenarioDAO.dataMigration.CustomScenarioRepositoryImpl$$EnhancerBySpringCGLIB$$56784e2f.handleMigration(<generated>)
        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.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
        at <unknown class>.invoke(Unknown Source)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
        at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
        at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:638)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
        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:97)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
        at com.sun.proxy.$Proxy95.handleMigration(Unknown Source)
        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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
        at com.sun.proxy.$Proxy95.handleMigration(Unknown Source)
        at com.xyz.projectnamescenario.scenarioDAO.service.ScenarioService.getScenarioById(ScenarioService.java:52)
        at com.xyz.projectnamescenario.scenarioDAO.controller.ScenarioController.getScenario(ScenarioController.java:52)
        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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:866)

If I am using MongoOperations.findAndReplace() with collectionName, then no exception and document is updated.
Screen Shot 2022-05-20 at 11 03 31

Please let me know if this is a known issue and if this is the most efficient way to rename fields in nested array.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 20, 2022
@christophstrobl
Copy link
Member

christophstrobl commented May 23, 2022

The exception is thrown because the name of the target collection cannot be derived from the given replacement type org.bson.Document which, unlike a domain type like eg. Scenario.class, is a store native type and does not hold any collection information.
I've to admit that there's room for improvement regarding the exception message and the javadoc. Esp. the latter mentions the collection name aspect, but not its implications.

@christophstrobl christophstrobl added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels May 23, 2022
mp911de added a commit that referenced this issue Sep 16, 2022
See #4061
Original pull request: #4062.
mp911de pushed a commit that referenced this issue Sep 16, 2022
We now provide a better worded exception message when trying to derive the collection name for a type that is not considered a user types (such as org.bson.Document).
Update the Javadoc to hint to the error.

Closes #4061
Original pull request: #4062.
mp911de added a commit that referenced this issue Sep 16, 2022
See #4061
Original pull request: #4062.
mp911de pushed a commit that referenced this issue Sep 16, 2022
We now provide a better worded exception message when trying to derive the collection name for a type that is not considered a user types (such as org.bson.Document).
Update the Javadoc to hint to the error.

Closes #4061
Original pull request: #4062.
mp911de added a commit that referenced this issue Sep 16, 2022
See #4061
Original pull request: #4062.
@mp911de mp911de changed the title mongoTemplate.findAndReplace throw Couldn't find PersistentEntity for type class org.bson.Document! MongoTemplate.findAndReplace throws Couldn't find PersistentEntity for type class org.bson.Document! Sep 16, 2022
@mp911de mp911de added this to the 3.3.7 (2021.1.7) milestone Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
4 participants