Étendre le modèle
Nous avons réussi à manipuler les entités d'un modèle simple. Voyons comment rendre notre modèle plus complet pour nous rapprocher de l'utilisation de ToPIA dans le contexte d'une véritable application.
Ajouter une méthode à une entité
Dans ArgoUML, vous pouvez ajouter une méthode sur une entité. Pour cela, ajouter la méthode dans le modèle, sur l'entité elle-même. Si besoin, il faudra ajouter au modèle les types des paramètres ou de la valeur de retour.
ToPIA utilise le patron de conception Generation Gap pour séparer le code généré du code écrit par le développeur. Ainsi, le ré-génération n'écrase que du code généré et jamais du code utilisateur. Vous ne devez jamais modifier les classe générées mais seulement toucher aux implémentations qui héritent de ces classes.
Vous remarquerez que ToPIA a bien ajouté la méthode dans l'interface de l'entité mais à laisser l'implémentation abstraite. C'est donc à vous d'écrire le code dans le Impl.
Forcer le chargement d'une association
Utiliser une clé métier pour identifier les entité (naturalId)
Chaque entité possède une cré primaire topiaId, mais dans certains cas il est important d'avoir une notion d'unicité sur une ou plusieurs propriétés d'une entité, ce qu'on appele une clé métier. Le comportement souhaité serait de préserver l'unicité sur ces propriétés ainsi que la création d'un index pour optimiser l'accès aux données.
Il est donc nécessaire de préciser cette notion au niveau du modèle, cela par le biais du tagValue (également propriété hibernate) naturalId
fr.ird.observe.entities.referentiel.ParametrageTaillePoidsFaune.class.tagvalue.naturalIdMutable=false fr.ird.observe.entities.referentiel.ParametrageTaillePoidsFaune.attribute.sexe.tagvalue.naturalId=true fr.ird.observe.entities.referentiel.ParametrageTaillePoidsFaune.attribute.ocean.tagvalue.naturalId=true fr.ird.observe.entities.referentiel.ParametrageTaillePoidsFaune.attribute.ocean.tagvalue.notNull=false fr.ird.observe.entities.referentiel.ParametrageTaillePoidsFaune.attribute.espece.tagvalue.naturalId=true
Ici, les propriétés "sexe", "ocean" et "espece" forment la clé métier de l'entité "ParametrageTaillePoidsFaune". Par défaut les propriétés d'une clé métier sont non null, mais il est possible de préciser dans certains cas qu'une propriété peut l'être (comme ici avec "ocean").
Le naturalId provoque trois résultats :
- création d'un index unique en base.
- vérification dans hibernate de l'intégrité de l'entité à la création : il est donc nécessaire de créer l'entité avec des valeurs pour les propriétés de la clé métier (méthode create sur le dao).
- impossibilité de modifier les valeurs de ces propriétés sur une entité existante ; à moins de le préciser dans la configuration via le tagValue "naturalIdMutable" placé à "true" (déconseillé).
Le DAO de l'entité se voit ajouté les méthodes suivantes :
- createByNaturalId : qui permet de crée l'entité avec tout les naturalId
- createByNotNull : qui permet de crée l'entité avec tout les naturalId not null (donc obligatoire)
- existByNaturalId : qui permet de vérifié que l'entité correspondant au naturalId existe
- findByNaturalId : qui permet de chercher l'entité sur les naturalId
Ajouter des requêtes complexes
Ajouter une méthode à un DAO
Il est possible d'étendre un DAO avec des méthodes définies à partir du modèle (méthode différente entre version 2.2 et 2.4).
Il suffit de créer une interface contenant les méthodes à ajouter au dao. Cette interface doit avoir le stéréotype <<dao>>. De plus l'interface doit dépendre (lien de dépendance nommé explicitement 'dao') de la classe de l'entité. Le DAOImpl ne sera pas généré et devra être défini à la charge du développeur.
Exemple (présent dans topiatest.zargo dans les sources de topia-persistence) :
Ajout d'une méthode findAllByCompany sur une entité Contact. Chaque société à un ensemble d'employés (Employee) qui ont des contacts (Tel, Adresse, ...). Ces contacts ne sont pas unique à chaque employé. Il peut être intéressant de connaître directement tous les contacts d'une société directement avec le DAO:
public class ContactDAOImpl<E extends Contact> extends ContactDAOAbstract<E> { @Override public Set<Contact> findAllByCompany(Company company) throws TopiaException { ... } }
Une erreur de compilation apparaîtra si ce fichier n'existe pas (car non généré). La signature de la méthode est présente dans le DAOAbstract (ici ContactDAOAbstract), d'où le @Override.
- Note
- L'ajout du throws TopiaException est automatique et n'a pas besoin d'être spécifié au niveau du modèle.
Implémenter la méthode avec TopiaQuery
Vous pouvez, dans le DAO écrire vos requêtes directement en HQL, toutefois, l'API TopiaQuery vous permet d'écrire les requêtes avec une API générée, qui suit les évolutions du modèle plutôt que de coder le HQL en dur.
Voir TopiaQuery.