0

J'ai une entité auto-référencée nommée Catégorie. Une catégorie peut avoir une ou plusieurs catégories enfants. Une catégorie peut également avoir aucun enfant.L'entité auto-référencée dans NHibernate donne aux références d'objet une exception d'instance transitoire non enregistrée

J'ai créé l'entité et le mappage mais je reçois toujours cette exception.

NHibernate.TransientObjectException: objet fait référence à une instance transitoire non enregistrées - sauvegarder l'instance transitoire avant le rinçage ou ensemble une action en cascade pour la propriété à quelque chose qui rendrait AutoSave.

Est-ce que je fais quelque chose de mal avec la partie mapping?
Est-il possible de sauvegarder tous les objets parents et enfants en même temps?
Toute aide serait appréciée.

Voici le code

POCO

public class Category 
{ 
    private ICollection<Topic> _topics; 
    private ICollection<Category> _childCategory; 
    private ICollection<Media> _media; 
    private Category _parentCategory; 

    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual bool IsActive { get; set; } 

    public virtual Category ParentCategory 
    { 
     get { return _parentCategory ?? (_parentCategory = new Category()); } 
     protected set { _parentCategory = value; } 
    } 

    public virtual ICollection<Category> ChildCategory 
    { 
     get { return _childCategory ?? (_childCategory = new List<Category>()); } 
     protected set { _childCategory = value; } 
    } 


    public virtual void AddChild(Category childCategory) 
    { 
     childCategory.ParentCategory = this; 
    } 
} 

Mapping

public class CategoryMapping : IAutoMappingOverride<Category> 
{ 
    public void Override(AutoMapping<Category> mapping) 
    { 
     mapping.Map(c => c.Name).Length(30); 
     mapping.Map(c => c.Description).Length(160); 
     mapping.References(x => x.ParentCategory) 
      .Cascade.None() 
      .Column("ParentCategoryId"); 
     mapping.HasMany(x => x.ChildCategory) 
      .Inverse().Cascade.All() 
      .KeyColumn("ParentCategoryId"); 
    } 
} 

test Je crée des catégories parents et enfants et en essayant de sauver tous à o nce.

public void CanSaveAllNewObjectGraphFromCategory() { 
    #region Categories and Child 
    var categories = new sq.Category() 
    { 
     Description = "Category1", 
     IsActive = true, 
     Name = "Categoy1" 
    }; 

    var childCat = new List<sq.Category>() { 
     new sq.Category(){ 
      Description = "ChildCategory1", 
      IsActive = true, 
      Name = "CCategoy1" 
     }, 
     new sq.Category(){ 
      Description = "ChildCategory2", 
      IsActive = true, 
      Name = "CCategoy2" 
     } 
    }; 

    foreach (var item in childCat) 
    { 
     categories.AddChild(item); 
    } 
    #endregion 

    using (var tx = _session.BeginTransaction()) 
    { 
     _catRepo.AddNewCategory(categories); 
     tx.Commit(); // Error occurs when commit is executed. 
    } 
} 

Répondre

0

Il faudrait assigner les deux côtés des références

public virtual void AddChild(Category childCategory) 
{ 
    childCategory.ParentCategory = this; 
    // add to collection as well 
    _childCategory.Add(childCategory); 
} 
+0

Je reçois toujours la même exception après avoir affecté l'autre côté de la référence. –

0

Votre message d'erreur vous a donné deux options:

  • Enregistrez le cas transitoire avant le rinçage
  • action Set en cascade pour la propriété de quelque chose qui le rendrait autosave

La première option est simple: il suffit d'enregistrer chaque instance avant de valider la transaction

using (var tx = _session.BeginTransaction()) 
{ 
    foreach(var category in categories) 
    { 
    _session.SaveOrUpdate(category); 
    } 
    _catRepo.AddNewCategory(categories); 
    tx.Commit(); 
}