英文:
How to inject beans without interface in Mongock changelogs
问题
我正在将一个 Spring Boot 应用程序从 2.2.2 迁移到 2.2.3 的过程中。同时,由于迄今为止使用的版本 2.0.2 不再兼容,我也将 mongock 升级到了 4.1.16。
在版本 4.1.16 中,我有一个在 2.0.2 中运行良好但在 4.1.16 中不再工作的变更日志:
@ChangeSet(order = "001", id = "initDatabaseParametre", author = "xxxxx")
public void initDatabaseParametre(ParametreManager parametreManager, ObjectMapper mapper) throws IOException
// something
}
在 4.1.16 中,我遇到了以下异常,因为 ObjectMapper 不是一个接口(com.fasterxml.jackson.databind.ObjectMapper):
io.changock.migration.api.exception.ChangockException: 在方法[ChangelogInitDatabase.initDatabaseParametre] 中的错误: 类型为 [ObjectMapper] 的参数必须是一个接口
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: 类型为 [ObjectMapper] 的参数必须是一个接口
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
我在变更日志中需要 ObjectMapper,因为我的迁移过程会读取 JSON 文件。
英文:
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.
答案1
得分: 2
正如您在Mongock文档的“在changeSet方法中使用自定义beans”部分中所看到的,您在changeSet中使用的自定义beans必须是接口。
在这里有一些解释。
然而,您可以告诉Mongock您不想要这样做。较不侵入性的机制是通过在您的changeSet参数上添加@NonLockGuarded
注释,如本节所述。
这种方法的缺点是您需要在所有的changeSet中使用该bean时每次都添加注释。也许一种更方便但更具侵入性的方式是在您的bean类型(在这种情况下是ObjectMapper)上添加相同的注释,如本节所述。
由于我假设这是jackson的ObjectMapper,与所有这些不同,您可以将SpringContext作为参数,并从中获取ObjectMapper bean,但出于明显的原因,这并不理想(这适用于任何类型的bean)。
英文:
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.
However, you can tell Mongock you don't want that. The less intrusive mechanism is by adding the annotation @NonLockGuarded
to you changeSet parameter, as explained in this section.
The down side of that approach is that you need to add the annotation every time you use that bean in all your changeSets. Maybe a more convenient way, but also more intrusive, is by adding the same annotation to your bean's type, in this case ObjectMapper, as explained in this section.
As I assume it's the jackson's ObjectMapper, instead all of this, you can take the SpringContext as parameter and get ObjectMapper bean from it, but it's not ideal, for obvious reasons(this applies to any kind of bean)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论