ToPIA Migration Service est un module ToPIA chargé d'effectuer la migration d'une base de données existante sans perte de données.
Cette page décrit un second service de migration où c'est l'utilisateur qui indique les scripts sql à effectuer pour chaque changement de version.
Ce service est plus léger que le service automatique et a quelques restrictions :
un seul modèle à migrer
un callback unique est requis (celui écrit par l'utilisateur)
Ce service doit disposer de quelques proprietés de configuration pour effectuer la migration d'une base de données.
Ces propriétés sont fournies au service via un TopiaContext et font donc partie de la configuration de l'application.
hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.connection.username=sa hibernate.connection.password= hibernate.connection.driver_class=org.h2.Driver topia.persistence.directories=directory1,directory2 topia.persistence.classes=classImpl1,classImpl2
Ces informations servent à créer une configuration hibernate (qui contient les informations de connexion et les mappings de l'application).
Les lignes commencant par "hibernate" sont spécifiques à hibernate et au type de base de données utilisé. Les lignes suivantes sont spécifiques à ToPIA mais contiennent les mappings indispensable pour créer le schéma de la base de données après migration.
La configuration doit contenir ces propriétés :
topia.service.migration.mappingsdir=oldmappings topia.service.migration.modelname=model
qui spécifie le répertoire de recherche des anciens mappings pour l'unique modèle.
Ce dossier contient ensuite un sous-dossier pour le modèle comportant chacun un sous-dossier par version par version (nommé X, *X* étant la version), avec pour chaque dossier, l'ensemble des mappings hibernate de cette version.
Exemple :
oldmappings/
model1/
1/
Class1.hbm.xml
Class2.hbm.xml
Class3.hbm.xml
2/
Class1.hbm.xml
Class2New.hbm.xml
Class3.hbm.xml
2.2/
Class2.hbm.xml
Class3.hbm.xml
Class4New.hbm.xml
La configuration doit contenir une propriété :
topia.service.migration.version=3.5.1 (exemple)
Cette propriété renseigne la version courante de l'application. Le modèle de classes doit contenir un tag "version" indiquant la version courante du modèle.
Lors de la migration ces deux versions seront comparées pour déterminer les mappings à utiliser.
Plus précisement, on cherche à partir des anciens mappings quelles versions peuvent être appliquées entre la version de la base et la version de l'application.
On doit définir une classe de type ManualMigrationCallback, pour donner les les actions à réaliser pour chaque migration de version. Dans ce callback, l'utilisateur doit indiquer s'il faut migrer la base de données.
Ce callback doit implémenter ManualMigrationCallback et se trouver dans la configuration:
topia.service.migration.callbackhandler=org.nuiton.test.MyMigrationCallback
Enfin pour utiliser le service, il faut l'activer. La configuration doit contenir la propriétés suivante :
topia.service.migration=org.nuiton.topia.migration.ManualMigrationEngine
Il est possible de ne pas déclancher automatiquement le service de migration au démarrage du service, cela peut être utile lorsque l'on veut effectuer des tâches sur la base avant d'effectuer une éventuelle migration.
Pour bloquer la migration au démarrage, on ajoute dans la configuration de ToPIA
topia.service.migration.migrate.on.init=false
Il est ensuite possible de récupérer le service de migration et d'effectuer la migration à partir d'un topiaContext :
ManualMigrationEngine service = (ManualMigrationEngine) ctxt.getService(TopiaMigrationService.class); service.doMigrateSchema();
Ce module étant un service ToPIA, il doit être activé pour pouvoir s'exécuter.
Il commence par se connecter au SGBD, vérifie si les versions diffèrent, et effectue la migration si besoin.
Dans le cas où la version ne peut pas être deterninée, il considère que le schema en base est en version V0 (les mppings de cette version doivent être fournit). Dans ce cas, il effectue en plus une détection des tables pour savoir si le schéma existe deja. S'il n'existe pas, il ne tente donc pas d'effetuer une migration.
Pour savoir comment migrer les données, le développeur doit écrire une méthode par version de base, donc on doit avoir autant de méthodes que de versions détectées dans les ancines mappings sauf pour la version V0.
Ces méthodes sont de la forme
migrateTo_XXX
où XXX est la version tranformée en identifiat java valide.
Exemple :
migrateTo_1_0_0 (pour la version 1.0.0)
Dans le cas où l'application est ammenée à créer un schéma de base de données, ou à mettre à jour le schéma, elle doit en informer le module de migration pour que celui-ci renseigne la version du schéma créé.
Le module s'enregistre automatiquement aupres de ToPIA pour savoir quand celui-ci a créé un nouveau schéma. Il renseigne donc automatiquement la version par la suite.