I have a Collection of documents that looks like:
[
{
"firstName" : "Foo",
"phone" : "+1 111 1111",
"car": "Toyota"
},
{
"firstName" : "Bar",
"phone" : "+2 222 2222",
"car": "Honda"
}
]
And I want to add a new field for every document in this collection "Persons", I'm able to execute a syntax on console, but since I need the change to be stored somehow, we are using Mongock. And I can't find a way to execute a update
trough MongockTemplate
.
The { "key" : "value" }
for the documents are static, I don't even need variable to pass them, the final documents should look like:
[
{
"firstName" : "Foo",
"phone" : "+1 111 1111",
"car": "Toyota",
"species" : "human"
},
{
"firstName" : "Bar",
"phone" : "+2 222 2222",
"car": "Honda",
"species" : "human"
}
]
I don't know how to execute a query like the one bellow, inside MongockTemplate
:
db.getCollection('Persons').update(
{},
{ $set: {"species": "human"} },
false,
true
)
Here's the StackTrace:
```java
22:18:48.237 [main] ERROR io.changock.runner.core.ChangockBase - Error in changock process. ABORTED MIGRATION
io.changock.migration.api.exception.ChangockException: Error in method[UpdateAddTypeField.updateAddTypeField] : 'com.mongodb.client.result.UpdateResult org.springframework.data.mongodb.core.MongoTemplate.updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update, java.lang.String)'
at io.changock.runner.core.MigrationExecutor.processExceptionOnChangeSetExecution(MigrationExecutor.java:195)
at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:102)
at io.changock.runner.core.MigrationExecutor.lambda$processSingleChangeLog$2(MigrationExecutor.java:94)
at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:80)
at io.changock.runner.core.MigrationExecutor.processSingleChangeLog(MigrationExecutor.java:94)
at io.changock.runner.core.MigrationExecutor.lambda$processAllChangeLogs$1(MigrationExecutor.java:88)
at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:80)
at io.changock.runner.core.MigrationExecutor.processAllChangeLogs(MigrationExecutor.java:88)
at io.changock.runner.core.MigrationExecutor.lambda$executeMigration$0(MigrationExecutor.java:69)
at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:80)
at io.changock.runner.core.MigrationExecutor.executeMigration(MigrationExecutor.java:69)
at io.changock.runner.spring.v5.core.SpringMigrationExecutor.executeMigration(SpringMigrationExecutor.java:38)
at io.changock.runner.core.ChangockBase.execute(ChangockBase.java:44)
at io.changock.runner.spring.v5.ChangockSpringBuilderBase$ChangockSpringApplicationRunner.run(ChangockSpringBuilderBase.java:110)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:786)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at com.hiden.subhiden.project.subhidenprojecterviceApplication.main(subhidenprojecterviceApplication.java:22)
Caused by: java.lang.reflect.InvocationTargetException: null
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 io.changock.runner.core.MigrationExecutor.executeChangeSetMethod(MigrationExecutor.java:174)
at io.changock.runner.core.MigrationExecutor.executeAndLogChangeSet(MigrationExecutor.java:127)
at io.changock.runner.spring.v5.core.SpringMigrationExecutor.executeAndLogChangeSet(SpringMigrationExecutor.java:44)
at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:100)
... 16 common frames omitted
Caused by: java.lang.NoSuchMethodError: 'com.mongodb.client.result.UpdateResult org.springframework.data.mongodb.core.MongoTemplate.updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update, java.lang.String)'
at com.github.cloudyrock.mongock.driver.mongodb.springdata.v2.decorator.impl.MongockTemplate.lambda$updateMulti$53(MongockTemplate.java:383)
at io.changock.driver.api.lock.guard.invoker.LockGuardInvokerImpl.invoke(LockGuardInvokerImpl.java:18)
at com.github.cloudyrock.mongock.driver.mongodb.springdata.v2.decorator.impl.MongockTemplate.updateMulti(MongockTemplate.java:383)
at com.hiden.subhiden.project.dbchangelogs.UpdateAddTypeField.updateAddTypeField(UpdateAddTypeField.java:32)
... 24 common frames omitted
22:18:48.315 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
com.github.cloudyrock.mongock.driver.mongodb.springdata.v2.decorator.impl.MongockTemplate.lambda$updateMulti$53(MongockTemplate.java:383)
The following method did not exist:
'com.mongodb.client.result.UpdateResult org.springframework.data.mongodb.core.MongoTemplate.updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update, java.lang.String)'
The method's class, org.springframework.data.mongodb.core.MongoTemplate, is available from the following locations:
jar:file:/home/johnnes/.m2/repository/org/springframework/data/spring-data-mongodb/3.0.5.RELEASE/spring-data-mongodb-3.0.5.RELEASE.jar!/org/springframework/data/mongodb/core/MongoTemplate.class
The class hierarchy was loaded from the following locations:
org.springframework.data.mongodb.core.MongoTemplate: file:/home/johnnes/.m2/repository/org/springframework/data/spring-data-mongodb/3.0.5.RELEASE/spring-data-mongodb-3.0.5.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.data.mongodb.core.MongoTemplate
Process finished with exit code 1
So, after many tried I've came upon the following solution: Get a instance of the MongoTemplate Impl trough the MongockTemplate and use it instead of the MongockTemplate. I've still got no ideia why it worked. If I figure it out I'll update this thread.
@ChangeSet(order = "1", id = "updateData", author = "J. Souza")
public void updateCollectionAddSpecieField(MongockTemplate mongockTemplate) {
MongoTemplate template = mongockTemplate.getImpl();
Query query = new Query();
query.addCriteria(where(SPECIES_FIELD).exists(false));
Update update = new Update();
update.set(SPECIES, HUMAN);
UpdateResult updateResult = template
.updateMulti(query, update, "Collection-Name");
log.info("Matched {} | Modified {}",
updateResult.getMatchedCount(), updateResult.getModifiedCount());
}