Я узнал, что миграция flywaydb с помощью java работает с подключением JDBC, а также поддерживает Spring через SpringTemplate, но flyway не работает с DAO.

Для таблиц / сущностей с большим количеством взаимосвязей гораздо проще выполнять миграцию с помощью DAO, а не sql.

Есть ли решение или обходной путь, чтобы справиться с этим?

3
Abreham Tesfu 28 Янв 2015 в 21:26

3 ответа

Лучший ответ

Во-первых, Flyway имеет собственную систему управления транзакциями и не использует обработку транзакций Spring.

Если ваши DAO расширяют JdbcDaoSupport, вы можете вручную создать экземпляр вашего DAO, а затем вручную ввести предоставленный JdbcTemplate в DAO:

public class MyJdbcMigration implements SpringJdbcMigration {
  public void migrate(JdbcTemplate jdbcTemplate) {
    MyJdbcDao dao = new MyJdbcDao();
    dao.setJdbcTemplate(jdbcTemplate);
    dao.updateDate();
  }
}
1
G Quintana 2 Фев 2015 в 13:31

Я знаю, что это происходит очень поздно, но для будущих посетителей с той же проблемой это может быть полезно.

Создатель Flyway (Аксель Фонтейн) ошибается в этом вопросе. Совершенно нормально переносить данные с помощью бизнес-логики, и нет проблем с курицей и яйцом, если вы не меняете структуру базы данных в своем сценарии обновления.

Один пример: у вас есть поле «пароль» в вашей базе данных, и это открытый текст. Из соображений безопасности теперь вы хотите использовать специальную хеш-функцию и хешировать все пароли в базе данных (она должна быть безопасной, а в базе данных нет функции для этого). Хеш-функция объявлена ​​в вашем UserDAO и вызывается при создании пользователя или изменении пароля. Хотя это не идеальный пример, существует множество возможных сценариев, в которых имеет смысл доступ к DAO для миграции.

К счастью, мой коллега по работе нашел решение проблемы, и для этого требуется всего около 5 строк кода. Вам также необходимо добавить Apache Deltaspike в свои зависимости, если это еще не сделано.

В вашем DAO добавьте импорт для BeanProvider:

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

Затем мы просто делаем DAO одноэлементным:

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

Это почти все. В вашем скрипте Flyway теперь вы можете получить доступ к DAO:

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

Объяснение: класс (VX_yourflywaymigrationscript) не управляется контейнером CDI, поэтому внедрить DAO невозможно. BeanProvider создан именно для этого - он может загружать Bean и давать вам ссылку, даже если вы не находитесь в контексте CDI.

Надеюсь, это поможет.

0
Benedikt Gansinger 9 Янв 2018 в 11:40

Ваши DAO полагаются на ту самую структуру, для изменения которой был разработан Flyway. Таким образом, у нас есть проблема с курицей и яйцом. Способ решить эту проблему - запустить Flyway до того, как остальная часть вашего приложения (включая DAO) будет инициализирована.

0
Axel Fontaine 29 Янв 2015 в 10:43