Я узнал, что миграция flywaydb с помощью java работает с подключением JDBC, а также поддерживает Spring через SpringTemplate, но flyway не работает с DAO.
Для таблиц / сущностей с большим количеством взаимосвязей гораздо проще выполнять миграцию с помощью DAO, а не sql.
Есть ли решение или обходной путь, чтобы справиться с этим?
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();
}
}
Я знаю, что это происходит очень поздно, но для будущих посетителей с той же проблемой это может быть полезно.
Создатель 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.
Надеюсь, это поможет.
Ваши DAO полагаются на ту самую структуру, для изменения которой был разработан Flyway. Таким образом, у нас есть проблема с курицей и яйцом. Способ решить эту проблему - запустить Flyway до того, как остальная часть вашего приложения (включая DAO) будет инициализирована.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.