2009-08-20 6 views
1

J'ai le cas d'utilisation suivant: Il existe une classe appelée Modèle et avec cette classe je peux créer des instances de la classe ActualObject (ActualObject copie ses données initiales à partir du modèle). La classe Template a une liste de Product: s.Masquage d'objets supprimés

Maintenant, voici la partie délicate, l'utilisateur devrait être en mesure de supprimer des produits de la base de données, mais ces suppressions peuvent ne pas affecter le contenu d'un modèle. En d'autres termes, même si un produit est supprimé, le modèle doit toujours y avoir accès. Cela pourrait être résolu en ajoutant un drapeau "supprimé" au produit. Si un produit est supprimé, il peut ne pas être recherché explicitement dans la base de données, mais il peut être extrait implicitement (par exemple via la référence dans la classe Template). L'idée sous-jacente est que lorsqu'un objet ActualObject est créé à partir d'un modèle, l'utilisateur est averti dans l'interface utilisateur que "Le modèle X a un produit Z avec les paramètres A, B et C, mais ce produit a été supprimé et ne peut pas être ajouté en tant que tel dans ActualObject Z ".

Mon problème est de savoir comment je devrais marquer ces objets supprimés comme effacés. Avant que quelqu'un suggère que juste mettre à jour l'indicateur de suppression au lieu de faire une requête de suppression réelle, mon problème n'est pas si simple. L'indicateur de suppression et son comportement doivent exister dans tous les POJO, pas seulement dans le produit. Cela signifie que je vais avoir des problèmes de cascade. Par exemple, si je supprime un modèle, les produits doivent également être supprimés et chaque produit doit faire référence à un objet prix qui doit également être supprimé et chaque prix peut faire référence à un objet TVA et ainsi de suite. Tous ces objets en cascade doivent être marqués comme supprimés.

Ma question est comment puis-je accomplir cela de manière sensée. Passer en revue chaque objet (qui est en train d'être supprimé) vérifier chaque champ pour les références qui devraient être supprimées, en passant par leurs références etc. est assez laborieux et les bogues sont faciles à glisser. Hibernate aurait de telles fonctionnalités intégrées. Une autre idée à laquelle je pensais était d'utiliser les intercepteurs Hibernate pour modifier une requête de suppression SQL réelle à une requête de mise à jour (je ne suis même pas sûr à 100% que c'est possible). Ma seule préoccupation est que Hibernate utilise des cascades dans les clés étrangères, en d'autres termes, les suppressions en cascade sont effectuées par la base de données et non par hibernate.

+0

Pourquoi avez-vous besoin de cascade? Marquez simplement le produit, puis, à partir du Pojo, faites flotter les clés étrangères vers le produit ou en charge depuis le filtre db par l'indicateur supprimé dans le produit. c'est à dire tenir le drapeau supprimé en un seul endroit – Mark

Répondre

2

Mon problème est de savoir comment je devrais marquer ces objets supprimés comme étant supprimés de .

Je pense que vous avez choisi une façon très complexe de résoudre la tâche. Il serait plus facile d'introduire ProductTemplate. Placez dans cet objet toutes les propriétés requises dont vous avez besoin. Et vous avez également besoin ici d'une référence à une instance Product. Au lieu de marquer Product vous pouvez simplement le supprimer (et supprimer toutes les autres entités, telles que les prix). Et, bien sûr, vous devriez nettoyer la référence dans ProductTemplate. Lorsque vous créez une instance de ActualObject, vous serez en mesure d'informer l'utilisateur avec le message approprié.

+0

Mon exemple était juste un cas d'utilisation, il y en a beaucoup d'autres et donc nous aimerions trouver une solution plus générale. –

+0

La restriction des rôles de classe est une stratégie générale. Vous pouvez le suivre tous les jours. –

1

Je pense que vous essayez de rendre les choses beaucoup plus compliquées qu'elles ne devraient être ... de toute façon, ce que vous essayez de faire est la manipulation Hibernate événements, jetez un oeil à Chapitre 12 Mise en veille prolongée Référence , vous pouvez choisir d'utiliser intercepteurs ou système d'événements. En tout cas ...bonne chance :)

+0

Comme je l'ai mentionné, j'avais pensé aux intercepteurs, mais je me demande si Hibernate utilise des cascades de clés étrangères dans la base de données, auquel cas je ne peux pas couvrir toutes les opérations de suppression en utilisant des intercepteurs. –

0

Si je comprends ce que vous demandez, vous ajoutez une relation @OneToMany entre le modèle et le produit, et sélectionnez vos règles en cascade, vous serez en mesure de supprimer tous les produits associés pour un modèle donné . Dans votre classe de produit, vous pouvez ajouter le drapeau "supprimé" comme vous l'avez suggéré. Ce drapeau supprimé serait exploité par votre couche de service/dao par exemple. vous pouvez tirer parti d'un concept de type getProdcuts (boolean includeDeleted) pour déterminer si vous devez inclure les enregistrements "supprimés" pour le retour. De cette façon, vous pouvez contrôler ce que les utilisateurs finaux voient, tout en exposant les fonctionnalités complètes aux utilisateurs métier internes.

+0

J'ai raté la mise à jour en cascade de la propriété "deleted" pour les objets enfants. Et si vous externalisiez ce concept dans un objet séparé, par exemple "Supprimé" et que vous utilisiez des références partagées du parent et de l'enfant. De cette façon, lorsque vous mettez à jour l'objet "Supprimé" du parent, tous les enfants associés auront également leur référence mise à jour. –

1
public interface Deletable { 
    public void delete(); 
} 

Tous vos objets supprimés implémentent cette interface. Dans leurs implémentations, mettez à jour le drapeau deleted et demandez-leur également d'appeler la méthode delete() de leurs enfants - ce qui implique que les enfants doivent également être Deletable.

Bien sûr, lors de la mise en œuvre, vous devrez déterminer manuellement quels enfants sont Deletable. Mais cela devrait être simple, au moins.

0

L'indicateur à supprimer doit faire partie de la classe de modèle elle-même. De cette façon, tous les objets que vous créez ont un moyen d'être marqué comme vivant ou supprimé. Le marquage de l'objet à supprimer devrait aller plus haut jusqu'à la classe de base.