Jak zaktualizować schemat bazy danych bez utraty danych za pomocą Hibernate?

Wyobraź sobie, że tworzysz aplikację Java EE przy użyciu Hibernate i JBoss. Masz uruchomiony serwer, który zawiera pewne ważne dane. Kolejną wersję aplikacji wypuszczasz raz na jakiś czas (1-2 tygodnie) i mają kilka zmian w warstwie trwałości:

  • nowe podmioty
  • usunięte byty
  • zmiany typu atrybutu
  • zmiany nazw atrybutów
  • zmiany relacji

Jak skutecznie skonfigurować system, który aktualizuje schemat bazy danych i zachowanie danych? Z tego co wiem (mogę się mylić), Hibernate nie wykonuje ograniczenia alter column, drop/alter.

Dziękuję, Artem B.

Author: artemb, 2009-04-10

8 answers

LiquiBase jest najlepszym rozwiązaniem. Posiada tryb integracji hibernate , który wykorzystuje Hbm2ddl Hibernate do porównania bazy danych i mapowania hibernate, ale zamiast aktualizować bazę danych automatycznie, wyświetla plik dziennika zmian liquibase, który można sprawdzić przed uruchomieniem.

Chociaż wygodniejsze, każde narzędzie, które porównuje bazę danych i mapowanie hibernate, popełni błędy. Zobacz też http://www.liquibase.org/2007/06/the-problem-with-database-diffs.html na przykład. Dzięki liquibase tworzysz listę zmian w bazie danych w formacie, który może przetrwać kod z oddziałami i połączeniami.

 16
Author: Nathan Voxland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-10 00:22:02

Osobiście śledzę wszystkie zmiany w migracyjnym skrypcie SQL.

 3
Author: Maurice Perry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-10 15:57:13
 3
Author: Blake Pettersson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-10 16:04:25

Możesz użyć https://github.com/Devskiller/jpa2ddl narzędzie, które zapewnia wtyczkę Maven i Gradle i jest w stanie generować automatyczne migracje schematów dla Flyway w oparciu o encje JPA. Zawiera również wszystkie właściwości, dialekty, typy użytkowników, strategie nazewnictwa itp.

 3
Author: Jakub Kubrynski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-27 21:58:21

Dla jednej aplikacji używam SchemaUpdate, który jest wbudowany do hibernacji, prosto z klasy bootstrap, więc schemat jest sprawdzany za każdym razem, gdy aplikacja się uruchamia. To zajmuje się dodawaniem nowych kolumn lub tabel, co jest głównie tym, co dzieje się z dojrzałą aplikacją. Aby poradzić sobie ze specjalnymi przypadkami, takimi jak upuszczanie kolumn, bootstrap po prostu ręcznie uruchamia ddl w try/catch, więc jeśli został już upuszczony raz, po prostu cicho wyrzuca błąd. Nie jestem pewien, czy zrobiłbym to z krytycznymi danymi w produkcji aplikacja, ale przez kilka lat i setki wdrożeń nigdy nie miałem z nią problemu.

 2
Author: Brian Deterling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-11 15:30:10

W dalszej odpowiedzi na to, co Nathan Voxland powiedział o LiquiBase , Oto przykład, aby wykonać migrację pod Windows dla bazy danych mySql:

Umieść łącznik mysql w folderze lib na przykład w dystrybucji liquibase.

Utwórz właściwości pliku liquibase.properties in the root of the liquibase distribution and insert this recurrent lines:

driver: com.mysql.jdbc.Driver
classpath: lib\\mysql-connector-java-5.1.30.jar
url: jdbc:mysql://localhost:3306/OLDdatabase
username: root
password: pwd

Generowanie lub pobieranie zaktualizowanej bazy danych pod inną nazwą na przykład NEWdatabase.

Teraz usuniesz różnice w pliku .xml z następującym wierszem poleceń:

liquibase diffChangeLog --referenceUrl="jdbc:mysql://localhost:3306/NEWdatabase" 
--referenceUsername=root --referencePassword=pwd > C:\Users\ME\Desktop\Migration.xml

Na koniec wykonaj aktualizację przy użyciu właśnie Wygenerowanej migracji .plik xml:

java -jar liquibase.jar --changeLogFile="C:\Users\ME\Desktop\Migration.xml" update

NB: wszystkie te linie poleceń powinny być wykonywane z katalogu domowego liquibase, gdzie liquibase.bat/.sh i liquibase.słoiki są obecne.

 2
Author: Jad B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-17 09:28:04

Używam zadania hbm2ddl ant do generowania mojego ddl. Istnieje opcja, która wykona zmianę tabel/kolumn w Twojej bazie danych.

Proszę zobaczyć atrybut "update" zadania ant hbm2ddl:

Http://www.hibernate.org/hib_docs/tools/reference/en/html/ant.html#d0e1137

Update( default: false): Try and create skrypt aktualizacji reprezentujący "delta" między tym co jest w baza danych i jakie mapowania sprecyzuj. Ignoruje tworzenie/aktualizowanie atrybuty. (Do Nie używaj przeciwko bazy danych produkcyjnych, brak gwarancji na wszystko, co właściwe delta może być generowane ani że bazowe baza danych może faktycznie wykonać potrzebne operacje)

 1
Author: Matt Sidesinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-11 01:25:11

Możesz również użyć DBMigrate. Jest podobny do Liquibase:

Podobne do 'rake migrate' dla Ruby na Rails Biblioteka ta pozwala na zarządzanie aktualizacje baz danych dla Twojej Javy aplikacje.

 0
Author: Hendy Irawan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-09 09:07:32