2 votes

Pourquoi l'ajout de cette ligne perturbe-t-il mon mappage NHibernate ?

J'ai un ClassMap très simple

public class ContentMap : ClassMap<Content>
{
    public ContentMap()
    {
       // Basic property mapping

       // Parent property mapping
       References(x => x.Category).Column("CategoryId");
    }
}

En utilisant cette méthode, mes mappings fonctionnent parfaitement bien et les Category n'est pas nulle.

Si j'essaie d'ajouter cette ligne en dessous de la première référence

References(x => x.LastActive).Column("LastActiveSubCategoryId");

Mes mappings ne sont pas bons.

Si LastActiveSubCategoryId est nulle, Category s'adapte parfaitement. Si elle n'est pas nulle, LastActiveSubCategoryId sera défini mais alors CategoryId est nulle.

Les propriétés elles-mêmes sont simples

public virtual Category Category { get; set; }

public virtual SubCategory LastActive { get; set; }

Il n'y a rien de complexe dans le Category o SubCategory mappings non plus. Ils ressemblent beaucoup aux ContentMap classe (avec une seule ligne de référence)

Une idée de ce qui pourrait provoquer ce comportement ? Puis-je utiliser une seule référence ?

Mise à jour

J'ai regardé le SQL et c'est ce qui semble se passer, j'espère que quelqu'un pourra m'aider à comprendre pourquoi.

Le site Content est insérée dans la base de données sans problème avec l'option CategoryId y LastActiveSubCategoryId nul.

Le site Category est insérée, puis une instruction de mise à jour met à jour l'entité Content en ne mettant à jour que le CategoryId et rien d'autre.

S'il n'y avait pas SubCategory tout serait parfait à ce stade.

S'il existe un SubCategory puis, quelques déclarations plus tard, il est inséré et ensuite l Category est mis à jour. Dans la déclaration de mise à jour, plusieurs valeurs différentes sont modifiées (certaines n'ont pas besoin de l'être puisqu'elles n'ont pas changé depuis l'insertion), notamment la valeur CategoryId y SubCategoryId . Sauf que maintenant CategoryId est nulle et LastActiveSubCategoryId ne l'est pas.

Alors pourquoi CategoryId sera nulle lors de la mise à jour ?

Mise à jour 2

Le code que j'utilise pour insérer les objets ne sert pour l'instant qu'à des tests de base. Voici les morceaux de code pertinents :

Category category = new Category();
dao.Save(category);

Content content = new Content();
category.AddContent(content); // Adds it to a list, like in the tutorial mBotros posted
dao.Save(Content);

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory);
dao.Save(subCategory);

// On the Content class
public virtual void AddSubCategory(SubCategory subCategory)
{
   SubCategories.Add(subCategory);
   LastActive = subCategory;
}

1voto

Daniel Schilling Points 3192

Il existe une référence circulaire dans le schéma de votre base de données, ce qui peut rendre l'insertion de lignes délicate.
Content références SubCategory et SubCategory références Content . Si vous essayez d'insérer des lignes en utilisant le bon vieux SQL, vous devrez no être en mesure de le faire :

/* this line does not work because SubCategory 2 does not exist yet */
insert into Content (Id, LastActiveSubCategoryId) values (1, 2);
insert into SubCategory (Id, ContentId) values (2, 1);

Vous devriez plutôt faire quelque chose comme ceci :

insert into Content (Id, LastActiveSubCategoryId) values (1, null);
insert into SubCategory (Id, ContentId) values (2, 1);
update Content set LastActiveSubCategoryId = 2 where Id = 1;

Vous devez garder cela à l'esprit lorsque vous persistez vos entités NHibernate. Modifier AddSubCategory de ne pas mettre LastActive . Sauvegardez d'abord les deux entités, puis fermez la boucle.

// ... code to save Category and Content, then...

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory); // modified to *not* set LastActive
dao.Save(subCategory);

content.LastActive = subCategory;
dao.Update(content);

0voto

Diego Mijelshon Points 40314

Vous mentionnez un LastActiveId qui n'est pas dans le code que vous avez montré.

Essayez-vous par hasard de mapper une colonne à la fois comme référence et comme propriété scalaire ?

Mise à jour Soit votre extrait de code est encore incomplet, soit il vous manque la transaction/flush qui provoquera les mises à jour. De plus, avez-vous à la fois une collection (non affichée) appelée SubCategories y une propriété appelée LastActive ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X