Roie Beck
Roie Beck

Reputation: 1175

Mongock migration fails to run mongockSpringLegacyMigration

I am trying to run mongock to handle my DB migration with versioning, but getting an exception from the mongock infrastructure, Also please note I am not using spring-boot only the spring bean system, there is no option for me to use spring boot...

Pom and code snippet :

            <dependency>
                <groupId>com.github.cloudyrock.mongock</groupId>
                <artifactId>mongock-standalone</artifactId>
                <version>4.1.19</version>
            </dependency>
            <dependency>
                <groupId>com.github.cloudyrock.mongock</groupId>
                <artifactId>mongodb-springdata-v2-driver</artifactId>
                <version>4.1.19</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-mongodb</artifactId>
                <version>2.1.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.mongodb</groupId>
                <artifactId>mongo-java-driver</artifactId>
                <version>3.8.2</version>
            </dependency>

Code:

@Configuration
@Import({MongoSelectorContext.class})
public class MongockBeans {

    private final MongoSelectorContext mongoSelectorContext;

    public MongockBeans(MongoSelectorContext mongoSelectorContext) {
        this.mongoSelectorContext = mongoSelectorContext;
    }

    @Bean
    public void updateMongoTemplateSchema() {
        MongoTemplate mongoTemplate = mongoSelectorContext.mongoTemplateProvider().getMongoTemplateByDatabaseAlias("test");
        MongockStandalone.builder()
                .setDriver(SpringDataMongo2Driver.withDefaultLock(mongoTemplate))
                .addChangeLogClass(TestChangeLog.class)
                .buildRunner().execute();
    }
}

Mongo template is provided as it should But I am getting the following error thrown, error is thrown from mongock and not from my changeset, it doesn't even execute my change set. any help would be appriciate

Exception in thread "main" java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongockBeans': Invocation of init method failed; nested exception is io.changock.migration.api.exception.ChangockException: Error in method[MongockV3LegacyMigrationChangeRunAlwaysLog.mongockSpringLegacyMigration] : Wrong parameter[MongockLegacyMigration] with name: legacy-migration
    at com.citi.qi.core.platform.CorePlatformLauncher.start(CorePlatformLauncher.java:39)
    at com.citi.quickinsight.evaluation.engine.EngineMain.main(EngineMain.java:35)
...
Caused by: io.changock.migration.api.exception.ChangockException: Error in method[MongockV3LegacyMigrationChangeRunAlwaysLog.mongockSpringLegacyMigration] : Wrong parameter[MongockLegacyMigration] with name: legacy-migration
    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.core.ChangockBase.execute(ChangockBase.java:49)
    at com.citi.quickinsight.MongockBeans.updateMongoTemplateSchema(MongockBeans.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
    ... 14 more
Caused by: io.changock.driver.api.common.DependencyInjectionException: Wrong parameter[MongockLegacyMigration] with name: legacy-migration
    at io.changock.runner.core.MigrationExecutor.lambda$getParameter$4(MigrationExecutor.java:182)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at io.changock.runner.core.MigrationExecutor.getParameter(MigrationExecutor.java:182)
    at io.changock.runner.core.MigrationExecutor.executeChangeSetMethod(MigrationExecutor.java:171)
    at io.changock.runner.core.MigrationExecutor.executeAndLogChangeSet(MigrationExecutor.java:127)
    at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:100)
    ... 32 more

Upvotes: 1

Views: 4051

Answers (2)

Mongock team
Mongock team

Reputation: 1533

While the previous workaround works, this was due to Mongock bug #268, which has been fixed in version 4.2.3.BETA.

The actual issue is that when no package is set in the builder, the reflections library gets an empty package list and instead on return nothing, it returns everything in the classpath.

As 99% are not annotated, they are ignored, but it finds the legacy migration and runs it.

Solution: Just avoid calling the reflections library if the package list is empty

Upvotes: 2

Mongock team
Mongock team

Reputation: 1533

This is needed to be looked deeper, but as I guess you are on development environment, you can try this workaround, which is just temporally for you to keep working.

private MongockLegacyMigration getLegacyMigration() {
    MongockLegacyMigration mongockLegacyMigration = new MongockLegacyMigration();
    mongockLegacyMigration.setCollectionName("no-existing-collection");
    return mongockLegacyMigration;
}

@PostConstruct
public MongockStandalone.Runner updateMongoTemplateSchema(MongoTemplate mongoTemplate) {
    return MongockStandalone.builder()
            .setDriver(SpringDataMongo2Driver.withDefaultLock(mongoTemplate))
            .addChangeLogClass(ClientInitializerChangeLog.class)
            .setLegacyMigration(getLegacyMigration())
            .buildRunner();
}

Please note that you are providing a non existing legacyMigration. It's not the right/final solution but won't hurt and as you are in development(my assumption), this allows you to keep working.

Upvotes: 2

Related Questions