Как свойство spring.jpa.hibernate.ddl-auto точно работает в Spring?

130

Я работал над своим проектом загрузочного приложения Spring и заметил, что иногда возникает ошибка тайм-аута подключения к моей базе данных на другом сервере (SQL Server). Это происходит особенно, когда я пытаюсь выполнить миграцию скрипта, FlyWayно после нескольких попыток он работает.

Затем я заметил, что не указал spring.jpa.hibernate.ddl-autoв своем файле свойств. Я провел небольшое исследование и обнаружил, что его рекомендуется добавлять spring.jpa.hibernate.ddl-auto= create-dropв разработке. И измените его на: spring.jpa.hibernate.ddl-auto= nonein production.

Но на самом деле я не понимал, как это работает и как спящий режим генерирует схему базы данных с использованием create-dropили noneзначения. Не могли бы вы объяснить технически, как это действительно работает, и каковы рекомендации по использованию этого свойства в разработке и на рабочем сервере. Спасибо

МЕТТАЙБИ
источник
1
FWIW JPA 2.1 имеет стандартное свойство javax.persistence.schema-generation.database.action, поэтому на самом деле не вижу необходимости использовать специфические свойства поставщика JPA для генерации схемы.
Нил Стоктон,
@NeilStockton Одна из идей, которую мы изучаем с помощью Hibernate 6, - это возможность управлять генерацией схемы по-разному в зависимости от категорий; например, ваши таблицы orm могут быть такими, noneно вы можете захотеть, чтобы ваши таблицы Hibernate Search и Envers создавались с использованием, updateпоскольку они внутренне управляются этими проектами, и вы не хотите управлять ими вручную. Сейчас мы контролируем это глобально для всех таблиц, независимо от их происхождения / источника. Это будет еще одной причиной для использования параметров, зависящих от производителя, если вы хотите это использовать.
Нарос 05

Ответы:

217

Для записи spring.jpa.hibernate.ddl-autoсвойство является специфичным для Spring Data JPA и является их способом указать значение, которое в конечном итоге будет передано в Hibernate под известным ему свойством hibernate.hbm2ddl.auto.

Значения create, create-drop, validateи в updateосновном влияют как инструмент управление схемой будет управлять схемой базы данных при запуске.

Например, updateоперация будет запрашивать API-интерфейс драйвера JDBC для получения метаданных базы данных, а затем Hibernate сравнивает объектную модель, которую он создает, на основе чтения ваших аннотированных классов или сопоставлений HBM XML, и будет пытаться настроить схему на лету.

updateОперация, например , будет пытаться добавлять новые столбцы, ограничения и т.д. , но никогда не будет удалить столбец или ограничение , которое не могло существовать ранее , но больше не делает в рамках объектной модели из предыдущего выполнения.

Как правило, в сценариях тестового примера вы, скорее всего, будете использовать create-dropдля создания схемы, в тестовый пример добавляются некоторые фиктивные данные, вы запускаете тесты, а затем во время очистки тестового примера объекты схемы удаляются, оставляя пустую базу данных.

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

В производстве часто настоятельно рекомендуется использовать noneэто свойство или просто не указывать его. Это связано с тем, что администраторы баз данных обычно используют сценарии миграции на предмет изменений базы данных, особенно если ваша база данных используется несколькими службами и приложениями.

Нарос
источник
11
Да, никогда не используйте генерацию ddl в продакшене. Мы генерируем начальные сценарии для структуры таблицы с помощью ddl и привлекаем к процессу администратора базы данных. Затем мы включаем сценарии db как часть модуля развертывания и выполняем их с помощью Flyway при развертывании приложения. Когда нам нужно изменить базу данных, мы добавляем новые скрипты в следующую версию приложения и выполняем развертывание в промежуточной стадии. Flyway автоматически определит текущую версию и запустит сценарии, необходимые для приведения базы данных к последней версии. Если все работает, запускаем в продакшн.
Клаус Гроенбек
1
что, если мы не укажем это свойство? например, у меня есть собственное обновление <bean id = "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> ... <prop key = "hibernate.hbm2ddl.auto"> </prop> У меня было это и по какой-то причине мои таблицы всегда удалялись, пока я не добавил вышеупомянутое свойство ;; ps: извините за образец кода)
Кыган Ион
11
Почему не validateв производственной среде?
Шамаль Карунаратне
21
@ShamalKarunarathne Приложения могут использоваться validateв производственной среде , но, как правило, это должна быть настройка, которую вы используете в своей среде качества / тестирования, чтобы убедиться, что сценарии базы данных, которые вы написали или применили к инструменту миграции базы данных, точны. Еще одна причина не использовать validateв производственной среде заключается в том, что это может стать узким местом во время процесса запуска вашего приложения, особенно если ваша объектная модель довольно обширна по размеру или если в игру вступают другие факторы, связанные с сетью.
Нарос
1
Без точной трассировки стека сложно строить предположения; однако первое, что я предполагаю, orderэто то, что синтаксический анализатор SQL неправильно интерпретирует, поскольку это ключевое слово, если оно не экранируется.
Нарос