Comment migrer les version d'un schema de base de données
Lorsque des modifications sont effectuer dans une application qui impacte le schema de base de données, celui doit subir des migrations. ToPIA fournit une API visant a assister le developpeur pour migrer un schema de base de données.
Approche
TODO approche migration par copy TOOD approche migration par requette sql
Configuration
Pour commencer, topia doit connaitre l'ensemble des versions de la base de données, et la version actuelle de l'application. Si la version de l'application diffère de celle de la base de données, une migration sera effectuée. Après la migration, la version de la base de données est égale à celle de l'application.
Dépendances
La migration est effectuée par le service de migration de ToPIA. Il est necessaire de l'ajouter explicitement.
<dependency> <groupId>org.nuiton.topia</groupId> <artifactId>topia-service-migration</artifactId> <version>2.5.3</version> <scope>compile</scope> </dependency>
Class de definition des migration
Pour commencer, il faut créer la classe definissant les versions.
public class DatabaseMigrationClass extends TopiaMigrationCallbackByClass { protected static final Version VERSION_1 = new Version("1"); protected static final Version VERSION_2 = new Version("2"); protected static final Version VERSION_3 = new Version("3"); public DatabaseMigrationClass() { super(new MigrationResolver()); } protected static class MigrationResolver implements MigrationCallBackForVersionResolver { @Override public Class<? extends MigrationCallBackForVersion> getCallBack(Version version) { Class<? extends MigrationCallBackForVersion> result = null; if (version.equals(VERSION_1)) { result = MigrationV0V1.class; } else if (version.equals(VERSION_2)) { result = MigrationV1V2.class; } else if (version.equals(VERSION_3)) { result = MigrationV2V3.class; } return result; } } @Override public Version[] getAvailableVersions() { Version[] result = new Version[] { VERSION_1, VERSION_2, VERSION_3 }; return result; } @Override public Version getApplicationVersion() { Version appVersion = new Version(MyAppDAOHelper.getModelVersion()); return appVersion; } @Override public boolean askUser(Version dbVersion, List<Version> versions) { return true; } }
Classes de migration de version
Ensuite, il faut créer une classe par migration.
Par exemple, voici la classe migrant le shema de la version 0 à la version 1 : MigrationV0V1.
public class MigrationV0V1 extends MigrationCallBackForVersion { public MigrationV0V1(Version version, TopiaMigrationCallbackByClass callBack) { super(version, callBack); } @Override protected void prepareMigrationScript(TopiaContextImplementor tx, List<String> queries, boolean showSql, boolean showProgression) throws TopiaException { queries.add("alter table SETOFVESSELS add column TECHNICALEFFICIENCYEQUATION VARCHAR(255);"); queries.add("alter table STRATEGY add column INACTIVITYEQUATIONUSED BIT default false;"); queries.add("alter table STRATEGY add column INACTIVITYEQUATION VARCHAR(255);"); queries.add("alter table STRATEGYMONTHINFO alter NUMBEROFTRIPS double;"); queries.add("alter table STRATEGYMONTHINFO alter MININACTIVITYDAYS double;"); } }
Configuration du topia context
Pour finir, il faut ajouter l'utilisation de la migration par ces classe dans le topia context. En effet, la migration est effectuée automatiquement lors de l'ouverture d'un TopiaContext.
Configuration:
config.put(TopiaMigrationService.TOPIA_SERVICE_NAME, TopiaMigrationEngine.class.getName()); config.put(TopiaMigrationService.MIGRATION_CALLBACK, DatabaseMigrationClass.getName());
ou dans un fichier de properties :
topia.service.migration=org.nuiton.topia.migration.TopiaMigrationEngine topia.service.migration.callback=org.test.myapp.DatabaseMigrationClass
Kettle
Une autre idee est de ne pas utiliser hibernate mais kettle pour la migration des données. Nous aurions de la même façon dans le nom des tables un numero de version de schéma. Un fichier kettle decrirait la migration d'une version à une autre. Et les différents fichiers serait chaînés pour arriver au schéma souhaité.