Ответ
Liquibase выполняет каждый ChangeSet только один раз. Если ChangeSet уже был применен к БД, его повторное выполнение при изменении исходного кода не произойдет автоматически. Это механизм идемпотентности.
Основные причины и решения:
| Причина | Решение |
|---|---|
| 1. Изменение checksum | Liquibase хранит хэш (checksum) ChangeSet в таблице DATABASECHANGELOG. При изменении скрипта checksum не совпадает, и Liquibase отказывается выполнять ChangeSet, считая его измененным после применения. |
| 2. ChangeSet не помечен для повторного запуска | Используйте атрибут runOnChange="true". Тогда ChangeSet будет повторно выполняться при каждом изменении его содержимого. |
| 3. Необходимость принудительного перезапуска | Измените id или author ChangeSet. Это заставит Liquibase воспринять его как новый. |
Пример настройки ChangeSet для повторного выполнения при изменениях:
<changeSet id="add-email-column" author="dev" runOnChange="true">
<addColumn tableName="users">
<column name="email" type="varchar(255)"/>
</addColumn>
</changeSet>
Дополнительные шаги для диагностики:
- Проверить таблицу
DATABASECHANGELOG: Убедитесь, что ChangeSet записан и егоMD5SUMсоответствует текущему состоянию. - Сбросить checksum (осторожно!): Команда
liquibase clearCheckSumsсбросит все checksums, и при следующем запуске Liquibase пересчитает их. Используйте только в тестовых средах. - Проверить логи Liquibase: Включите детальное логирование (
logging.level.liquibase=DEBUGв Spring) для просмотра процесса валидации checksums. - Убедиться в автоматическом запуске: Проверьте конфигурацию (например,
spring.liquibase.enabled=trueиspring.liquibase.change-logв Spring Boot).
Важно: Стратегия runOnChange="true" подходит для изменяемых справочных данных или условий. Для структурных изменений (DDL) чаще создают новый ChangeSet с другим id.