Flyway Migration with java

前端 未结 3 1048
挽巷
挽巷 2021-01-15 14:32

I learnt flywaydb migration with java works with JDBC connection and also spring support through SpringTemplate, but flyway doesn\'t work with DAOs.

for tables/entit

相关标签:
3条回答
  • 2021-01-15 14:38

    Your DAOs rely on the very structure Flyway was designed to change. We therefore have a chicken and egg problem here. The way to solve this is to run Flyway before the rest of your application (including the DAOs) gets initialized.

    0 讨论(0)
  • 2021-01-15 14:38

    I know this comes very late, but for future visitors with the same problem this might be helpful.

    The creator of Flyway (Axel Fontaine) is actually wrong in this subject. It's perfectly fine to migrate data with business logic and there is no chicken and egg problem, as long as you do not change the structure of the database in your update script.

    One example: you have a field "password" in your database and it is clear text. Because of security concerns you now want to use a special hash function and hash all passwords in the database (it should be a secure one and the database does not have a function to do that). The hash function is declared in your UserDAO and called when the user is created or when they change their password. Although that's not a perfect example, there are many possible scenarios where accessing a DAO for the migration makes sense.

    Fortunately a work colleague of mine found a solution to the problem, and it's only requires around 5 lines of code. You also need to add Apache Deltaspike to your dependencies, if it isn't already.

    In your DAO, add an import for BeanProvider:

    import org.apache.deltaspike.core.api.provider.BeanProvider;
    

    Then we simply make the DAO a singleton:

    public static UserDao getInstance() {
        return BeanProvider.getContextualReference(UserDao.class, false, new DaoLiteral());
    }
    

    That's pretty much it. In your Flyway script you can now access the DAO:

    @Override
    public void migrate(Connection cnctn) throws Exception{
        UserDao userdao = UserDao.getInstance();
        List<User> userList = userdao.getAllUsers();
        ...
    }
    

    Explanation: the Class (VX_yourflywaymigrationscript) is not managed by the CDI Container, so it's not possible to inject the DAO. BeanProvider is made for exactly that - it can load a Bean and give you the reference, even if you are not in a CDI context.

    I hope that helps.

    0 讨论(0)
  • 2021-01-15 14:43

    First, Flyway has its own transaction managing system and does not use Spring transaction handling.

    If your DAOs extend JdbcDaoSupport, you could instantiate manually the your DAO and then manually inject the provided JdbcTemplate in the DAO:

    public class MyJdbcMigration implements SpringJdbcMigration {
      public void migrate(JdbcTemplate jdbcTemplate) {
        MyJdbcDao dao = new MyJdbcDao();
        dao.setJdbcTemplate(jdbcTemplate);
        dao.updateDate();
      }
    }
    
    0 讨论(0)
提交回复
热议问题