首页 > 解决方案 > How to inject beans without interface in Mongock changelogs

问题描述

I am in the process of migrate a spring boot application from 2.2.2 to 2.2.3. I also upgrade mongock to 4.1.16 as the version 2.0.2 used so far is not compatible anymore.

I have this changelog which works fine in 2.0.2 but not in 4.1.16 :

    @ChangeSet(order = "001", id = "initDatabaseParametre", author = "xxxxx")
    public void initDatabaseParametre(ParametreManager parametreManager, ObjectMapper mapper) throws IOException 
        // someting
    }

With 4.1.16 I have this exception because ObjectMapper is not an interface (com.fasterxml.jackson.databind.ObjectMapper) :

io.changock.migration.api.exception.ChangockException: Error in method[ChangelogInitDatabase.initDatabaseParametre] : Parameter of type [ObjectMapper] must be an interface
        at io.changock.runner.core.MigrationExecutor.processExceptionOnChangeSetExecution(MigrationExecutor.java:179)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:97)
        at io.changock.runner.core.MigrationExecutor.lambda$processSingleChangeLog$2(MigrationExecutor.java:89)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:75)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeLog(MigrationExecutor.java:89)
        at io.changock.runner.core.MigrationExecutor.lambda$processAllChangeLogs$1(MigrationExecutor.java:83)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:75)
        at io.changock.runner.core.MigrationExecutor.processAllChangeLogs(MigrationExecutor.java:83)
        at io.changock.runner.core.MigrationExecutor.lambda$executeMigration$0(MigrationExecutor.java:64)
        at com.github.cloudyrock.mongock.driver.mongodb.springdata.v3.SpringDataMongo3Driver.executeInTransaction(SpringDataMongo3Driver.java:108)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:73)
        at io.changock.runner.core.MigrationExecutor.executeMigration(MigrationExecutor.java:64)
        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 org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
        at com.myproject.MyApplication.main(MyApplication.java:23)
Caused by: io.changock.migration.api.exception.ChangockException: Parameter of type [ObjectMapper] must be an interface
        at io.changock.runner.core.DependencyManagerWithContext.getDependency(DependencyManagerWithContext.java:42)
        at io.changock.runner.core.MigrationExecutor.getParameter(MigrationExecutor.java:165)
        at io.changock.runner.core.MigrationExecutor.executeChangeSetMethod(MigrationExecutor.java:155)
        at io.changock.runner.core.MigrationExecutor.executeAndLogChangeSet(MigrationExecutor.java:111)
        at io.changock.runner.spring.v5.core.SpringMigrationExecutor.executeAndLogChangeSet(SpringMigrationExecutor.java:44)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:95)
        ... 19 common frames omitted

I need ObjectMapper in my changelogs because my migration process reads json files.

标签: javamongodbspring-bootmongock

解决方案


As you can see in the Using custom beans in changeSet methods section, in the Mongock's documentation, the custom beans you use in your changeSet must be interfaces.

Here there is some explanation.

但是,你可以告诉 Mongock 你不想要那个。侵入性较小的机制是通过将注释添加@NonLockGuarded到您的 changeSet 参数,如本节中所述。

这种方法的缺点是每次在所有变更集中使用该 bean 时都需要添加注释。也许一种更方便但也更具侵入性的方法是向 bean 的类型添加相同的注释,在本例中为 ObjectMapper,如本节所述

正如我假设它是杰克逊的 ObjectMapper,而不是所有这些,您可以将 SpringContext 作为参数并从中获取 ObjectMapper bean,但这并不理想,原因很明显(这适用于任何类型的 bean)


推荐阅读