当前位置: 首页 > 知识库问答 >
问题:

具有JPA依赖的Flyway Spring Boot Autowired Bean

谭宜
2023-03-14

共有1个答案

班浩皛
2023-03-14

由于我对JPA的依赖,我为此挣扎了很长时间。我要稍微修改一下我的问题的标题来反映这一点...

@AutoWiredbean是从ApplicationContext实例化的。我们可以创建一个不同的bean,即ApplicationContextAWare,并使用它“手动连接”我们的bean,以便在迁移中使用。

这里可以找到一个相当干净的方法。不幸的是,在使用JPA时,这会抛出一个未捕获的异常(特别是applicationcontext为null)。幸运的是,我们可以通过使用@dependson注释来解决这个问题,并在设置了ApplicationContext之后强制flyway运行。

首先,我们需要上面avehlies/spring-beans-flyway2中的springutility

package com.mypackage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtility implements ApplicationContextAware {

    @Autowired
    private static ApplicationContext applicationContext;

    public void setApplicationContext(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /*
        Get a class bean from the application context
     */
    public static <T> T getBean(final Class clazz) {
        return (T) applicationContext.getBean(clazz);
    }

    /*
        Return the application context if necessary for anything else
     */
    public static ApplicationContext getContext() {
        return applicationContext;
    }

}

然后,使用SpringUtility@dependson配置FlywayInitializer。我在这里扩展了FlywayAutoConfiguration,希望保留自动配置功能。这对我来说似乎很管用,只是关闭gradle.build文件中的flyway不再管用了,所以我不得不添加@profile(“!integration”)来防止它在测试期间运行。除此之外,自动配置似乎对我有效,但必须承认,我只运行了一次迁移。如果我错了,希望有人能纠正我。

package com.mypackage;

import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayConfiguration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.DependsOn;

import com.mypackage.SpringUtility;

@Configuration
@Profile("!integration")
class MyFlywayConfiguration extends FlywayConfiguration {
    @Primary
    @Bean(name = "flywayInitializer")
    @DependsOn("springUtility")
    public FlywayMigrationInitializer flywayInitializer(Flyway flyway){
        return super.flywayInitializer(flyway);
        //return new FlywayMigrationInitializer(flyway, null);
    }
}

为了完成这个示例,这里有一个迁移:

package db.migration;

import org.flywaydb.core.api.migration.spring.BaseSpringJdbcMigration;
import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Component;

import com.mypackage.repository.AccountRepository;
import com.mypackage.domain.Account;

import com.mypackage.SpringUtility;

import java.util.List;

public class V2__account_name_ucase_firstname extends BaseSpringJdbcMigration {

    private AccountRepository accountRepository = SpringUtility.getBean(AccountRepository.class);

    public void migrate(JdbcTemplate jdbcTemplate) throws Exception {

        List<Account> accounts = accountRepository.findAll();

        for (Account account : accounts) {

            String firstName = account.getFirstName();
            account.setFirstName(firstName.substring(0, 1).toUpperCase() + firstName.substring(1));
            account = accountRepository.save(account);

        }
    }
}

感谢github上的avehlies、stack overflow上的Andy Wilkinson和github上的OldIMP一路帮助我。

如果您使用的是最新版本的Flyway,请扩展BaseJavaMigration而不是BaseSpringJDBCMigration,因为后者不推荐使用。另外,看看下面用户Wim Deblauwe的两条评论。

 类似资料:
  • 我试图用Maven做一个小程序。我使用的是来自我大学教授的模板,我想使用log4j进行日志记录。当我在eclipse中运行该程序时,它工作得很好。然而,当我用“MVN install”创建jar并尝试用cmd运行程序时,我得到的是一个NoClassDefFoundError 我在这里还发现了这一点:NoClassDefFoundError在Maven依赖上,我尝试使用maven-shade-plu

  • 问题内容: 这是我目前拥有的并且可以正常工作: 现在,我想添加另一个依赖项。我将其更改为: 但是现在我收到此错误消息: FragmentFacebookLoginComponent依赖于多个作用域组件 我该如何解决?我如何有多个依赖关系? 如果我从一个组件中删除范围,则会收到此错误消息: AnotherComponent(无作用域)不能依赖范围内的组件 问题答案: 最后,我创建了一个具有正确范围的

  • 我有一个SpringBootWeb项目,它依赖于maven overlay war文件,这也是SpringWeb项目。pom中包含战争。xml。 我如何部署战争与Spring Boot应用程序,以便我可以使用属于战争文件的Restendpoint。我试图从STS启动应用程序,只需将其作为Java应用程序运行。当应用程序启动时,我只能看到属于Spring Boot项目的URL,但属于war文件的UR

  • DB是这样设置的。 AppDB AppLogDB AppAuditDB apparchivedb ... 我有一些例子,其中AppDB有引用其他表的视图/过程/等。也有其他DBs访问AppDB的情况(即ArchiveDB存储过程将从AppDB拉出)。 有了不同数据库之间的这种依赖关系,FlyWay是否可以按照所需的顺序处理迁移/清理?例如: 如果我有这样的脚本顺序 AppDB v1__create

  • 我正在为jboss ear应用程序编写一个EJB jar模块。我使用的是gradle,我不想试图从JBoss声明jar在运行时依赖的所有不同依赖项。是否有一种方法可以声明对目录树中所有文件的依赖关系。

  • 我有一个Android闭源模块,将在其他项目中用作库。它包含外部依赖项。 为了发布它,我用下面的gradle任务创建了一个Maven工件: 它生成.aar文件,即pom。xml等而没有问题。 然后我创建了一个依赖于我的库的项目。它会一直工作,直到需要访问外部依赖时,抛出一个类未找到异常。 如何编辑我的gradle任务以包含外部依赖项或至少对它们的引用?它们以mvnrepository.com和gi