Note that there are some explanatory texts on larger screens.

plurals
  1. POhow can I make nhibernate cascade save a set of objects with circular references?
    text
    copied!<p>I am assuming nhibernate can handle circular reference issues as I have not seen this mentioned otherwise in the docs or on google (but perhaps I have the wrong terms).</p> <p>Suppose I have a class which has as a member a reference to an instance of itself:</p> <p>e.g.</p> <pre><code>class A { A Other; } </code></pre> <p>I then create 2 objects and have them cross reference one another</p> <pre><code>A a1 = new A(); A a2 = new A(); a1.Other = a2; a2.Other = a1; </code></pre> <p>I want to produce a set of mappings for these classes such that if I attempt to save a in a session, it will also save b in such a way that b's reference to a is retained.</p> <p>At the moment I have produced a simple mapping using the many-to-one association (actually this is generated by fluent nhibernate but it looks OK on manual inspection)</p> <pre><code> &lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access=""&gt; &lt;class name="hibernate.experiment.CircularRefQn+A, hibernate.experiment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`A`" xmlns="urn:nhibernate-mapping-2.2"&gt; &lt;id name="Id" type="Int32" column="Id"&gt; &lt;generator class="identity" /&gt; &lt;/id&gt; &lt;many-to-one cascade="all" name="Other" column="Other_id" /&gt; &lt;/class&gt; &lt;/hibernate-mapping&gt; </code></pre> <p>But when I save, a1 does not save the reference to a2 in the database. How can I make it do this?</p> <p>example code using fluent nhibernate is here (requires nhibernate, fluent-nhibernate and nunit - if people want a stripped down version let me know).</p> <p>I also created an a3 object which refers to itself and this does not save as I would like.</p> <pre><code>using System.IO; using FluentNHibernate.Cfg; using FluentNHibernate.Mapping; using NHibernate.Tool.hbm2ddl; using NUnit.Framework; namespace hibernate.experiment { [TestFixture] public class CircularRefQn { [Test] public void Test() { var file = this.GetType().Name + ".db"; if (File.Exists(file)) File.Delete(file); var fcfg = Fluently.Configure() .Database(FluentNHibernate.Cfg.Db.SQLiteConfiguration.Standard .UsingFile(file)) .Mappings(m =&gt; { m.FluentMappings.Add(typeof(A.Map)); m.FluentMappings.ExportTo("."); }) .ExposeConfiguration(cfg =&gt; new SchemaExport(cfg).Create(true, true)) ; var sFactory = fcfg.BuildSessionFactory(); using (var s = sFactory.OpenSession()) { A a1 = new A(); A a2 = new A(); a1.Other = a2; a2.Other = a1; Assert.NotNull(a1.Other); Assert.NotNull(a2.Other); A a3 = new A(); a3.Other = a3; s.Save(a1); s.Update(a1); s.Save(a3); } using (var s = sFactory.OpenSession()) { foreach (var a in s.CreateCriteria(typeof(A)).List&lt;A&gt;()) Assert.NotNull(a.Other); } } public class A { public virtual int Id { get; set; } public virtual A Other { get; set; } public class Map : ClassMap&lt;A&gt; { public Map() { Id(x =&gt; x.Id); References(x =&gt; x.Other) .Cascade.All(); } } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload