I know this comes very late, but for future visitors with the same problem this might be helpful.
In my opinion, the creator of Flyway 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 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.