Depuis le début de l’utilisation de Generic System, nous avons créé des types, des instances, des attributs… et nous avons vu comment les supprimer en utilisant la fonctionnalité
remove().
Ah, au fait, il y a un terme générique pour désigner un type, une instance, un attribut, un holder, une relation ou encore un link : il s’agit tout simplement d’un
Generic.
Suppression d’un generic
Un generic peut être supprimé en utilisant la méthode remove().
Nous avions utilisé cet exemple pour supprimer un type :
1 2 3 4 5 6 7 8 9 |
Engine engine = new Engine(); Generic vehicle = engine.addInstance("Vehicle"); // Remove the type Vehicle vehicle.remove(); // Persist changes engine.getCurrentCache().flush(); |
Suppressions et dépendances
Comme dans toute base de données, il faut faire attention lors des modifications et particulièrement lors des suppressions.
Vous ne pouvez pas supprimer un
Generic si d’autres en dépendent : c’est la fameuse contrainte d’intégrité référentielle des bases de données relationnelles, qui existe également sur Generic System.
Le meilleur exemple pour comprendre est la suppression d’un type qui est relié à un autre.Reprenons notre exemple de
Vehicle et tentons une suppression avec dépendance.
Au fait, il y a une méthode que vous vous devez de connaître maintenant :
isAlive(). Elle vous indique si le generic sur lequel vous appliquez cette méthode est encore en vie. Autrement dit, cette méthode répondra
false si vous avez supprimé le generic en question.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Engine engine = new Engine(); Generic vehicle = engine.addInstance("Vehicle"); Generic color = engine.addInstance("Color"); Generic vehicleColor = vehicle.addRelation("VehicleColor", color); // Remove the type Vehicle vehicle.remove(); assert !vehicle.isAlive(); assert !vehicleColor.isAlive(); assert color.isAlive(); // Persist changes engine.getCurrentCache().flush(); |
Mais mais… Tu supprimes le type
Vehicle et la relation
VehicleColor est supprimée également ! Ca ne vient pas à l’encontre de ce que tu viens de nous dire ?
Vous avez raison. En fait, ce que je vous ai dit est presque vrai : un generic ne peut être supprimé s’il a des dépendances sauf si ces dépendances sont sur la base du generic.
Plus exactement, la contrainte d’intégrité référentielle est activée sur tous les axes sauf sur la base.
Mais vous pouvez changer ce comportement par défaut et activer également la contrainte sur la base. Voyons ça avec un exemple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Engine engine = new Engine(); Generic vehicle = engine.addInstance("Vehicle"); Generic color = engine.addInstance("Color"); vehicle.addRelation("VehicleColor", color); // Enable referential integrity for Vehicle in VehicleColor for the base : Vehicle engine.find(MetaRelation.class).enableReferentialIntegrity(ApiStatics.BASE_POSITION); // Persist changes engine.getCurrentCache().flush(); try { // Remove the type Vehicle vehicle.remove(); } catch (RollbackException e) { assert e.getCause() instanceof ReferentialIntegrityConstraintViolationException; } |
Il y a une petite subtilité quand même. La contrainte doit être activée non pas sur la relation mais sur le
Generic “au-dessus” de la relation.
De manière plus générale, la contrainte doit être activée sur le
Generic “au-dessus” du
Generic concerné.
Par exemple, le
Generic au-dessus d’une instance est son type. Celui au-dessus d’un holder est son attribut. Et celui au-dessus d’un link est sa relation.
Et le
Generic au-dessus de la relation ? Il s’agit de la
MetaRelation, la relation au-dessus de toutes les relations. Voilà pourquoi la contrainte est activée sur la
MetaRelation.
Quand au code
engine.find(MetaRelation.class), il demande juste à l'
Engine de chercher une classe.
Mais revenons à notre sujet de suppression et dépendances.
Bien, bien.
Et supposons que je souhaite que la suppression du type
Vehicle supprime également le type
Color qui est lié à ma relation
VehicleColor, c’est possible ?
Bien sûr, c’est ce qu’on appelle la suppression en cascade.
Suppression en cascade
Là encore, comme dans toute base de données, il est possible de spécifier si une suppression s’effectue ou non en cascade. Pour cela, il faut activer/désactiver la propriété système CascadeRemoveProperty. Là encore, cette propriété doit être activée sur le
Generic “au-dessus” du
Generic concerné.
Reprenons notre exemple classique de
Vehicle et activons cette propriété pour supprimer également le type
Color lors de la suppression du type
Vehicle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Engine engine = new Engine(); Generic vehicle = engine.addInstance("Vehicle"); Generic color = engine.addInstance("Color"); Generic vehicleColor = vehicle.addRelation("VehicleColor", color); // Disable default referential integrity for Vehicle in VehicleColor for the first target : Color engine.find(MetaRelation.class).disableReferentialIntegrity(ApiStatics.TARGET_POSITION); // Enable cascade remove for Color in VehicleColor engine.find(MetaRelation.class).enableCascadeRemove(ApiStatics.TARGET_POSITION); // Remove the type Vehicle vehicle.remove(); assert !vehicle.isAlive(); assert !vehicleColor.isAlive(); assert !color.isAlive(); // Persist changes engine.getCurrentCache().flush(); |
En résumé
- Un generic peut être supprimé en appelant la méthode remove().
- Un generic ne peut pas être supprimé si d’autres en dépendent : c’est la contrainte d’intégrité référentielle.
- Cette contrainte est activée par défaut sur tous les axes sauf sur la base.
- La méthode isAlive permet de savoir si un Generic est encore en vie.
- La propriété système CascadeRemoveSystemProperty peut être activée sur une relation en précisant l’axe c’est-à-dire la position du type dans la relation. Toute suppression d’un type entraînera la suppression du type dans ladite relation situées à cette position, c’est ce qu’on appelle une suppression en cascade.
Dans ce billet, nous sommes passés rapidement sur la notion d’axe. Nous allons approfondir ce sujet dans le billet suivant et revenir sur les relations.