2010-02-23 23 views
0

Je travaille sur un projet où les données persistantes peuvent être marquées pour suppression, mais restent dans la base de données ayant une colonne (is_deleted) définie sur TRUE.NHibernate mapping. Définir la collection d'éléments déclarés de sous-classe jointe et la propriété where

Cela fonctionne très bien en utilisant la propriété de mappage de classe de mise en veille prolongée "where" et en ajoutant where = "is_deleted = 0" aux balises. Mais cela échoue quand je déclare un ensemble d'éléments de sous-classe.

Cet exemple simplifié utilise la classe « Car » contenant une collection de membre de la classe « Wheel » qui hérite de la classe « carpart »:

<class name="Car" where="is_deleted = 0"> 
    <id name="Identifier" column="car_id"> 
    <generator class="native" /> 
    </id> 
    <set name="Wheels" lazy="true" where="is_deleted = 0"> 
    <key column="car_id" /> 
    <one-to-many class="Wheel" /> 
    </set> 
</class> 

<class name="CarPart" where="is_deleted = 0"> 
    <id name="Identifier" column="part_id"> 
    <generator class="native" /> 
    </id> 
    <property name="IsDeleted" /> 

    <joined-subclass name="Wheel" > 
    <key column="part_id" /> 
    <property name="radius" /> 
    </joined-subclass> 
</class> 

Si je dans le code tente d'accéder à la collection voiture .Wheels Je reçois une erreur SQL car la clause "where" s'applique à la table de la sous-classe "Wheel" à la place de sa super-classe "CarPart" où la propriété IsDeleted est réellement définie.

Le SQL généré ressemble à ceci:

select * from Wheel w inner join CarPart cp on... 
where w.is_deleted = 0 

plutôt que le

correct
select * from Wheel w inner join CarPart cp on... 
where cp.is_deleted = 0 
  • Est-ce un bug? Ou est-ce que je manque un détail ? La super-classe CarPart a déjà where = "is_deleted = 0", donc logiquement cela devrait s'appliquer à toutes les sous-classes définies ?
  • Existe-t-il d'autres méthodes pour ajouter un indicateur is_deleted à toutes les données persistantes is dans NHibernate?

Votre aide est très apprécié

Répondre

0

Je recommande vivement de créer une vue pour chaque table supprimer douce qui filtre les enregistrements supprimés et la carte de la vue dans votre modèle de domaine. Cela rendra la cartographie beaucoup plus facile.

Si votre base de données le prend en charge, vous pouvez créer un déclencheur INSTEAD OF DELETE sur les tables pour définir l'indicateur is_deleted au lieu de supprimer l'enregistrement. Cette combinaison avec les vues permet à votre modèle de domaine d'ignorer complètement les suppressions logicielles.

+0

Merci pour votre suggestion, même si un changement majeur d'architecture n'est pas possible maintenant. Ce qui fonctionne et est nettoyé à 99%, c'est que la colonne is_deleted soit mappée à la sous-classe (Wheel.IsDeleted plutôt que CarPart.IsDeleted). Cela signifie cependant que la table CarPart ne stocke pas les informations si une instance de sous-classe de Wheel (ou d'autres sous-classes) est supprimée ou non, ce qui serait l'idéal. Si vous récupérez tous les CarParts, vous aurez également des occurrences supprimées. Si vous récupérez toutes les roues, vous obtiendrez seulement où is_delete = 0, ce qui est acceptable. – Xult

+0

J'espère toujours que quelqu'un peut faire la lumière sur ce sujet. Je pense que le vrai problème est que la clause where est purement SQL. Pour implémenter ce que je veux, il faudrait que la clause where soit HQL, ce qui serait mieux de toute façon. – Xult