Hi, I am assuming it is possible to persist objects with circular references as neither google nor the manual seem to say this is impossible (or perhaps I have been using the wrong search terms). If this is the case I believe it stems from a fairly fundamental misunderstanding of how to persist a simple single object reference and have this cascaded upon save.
The best way to explain is in the example below. I basically create a class of the form:
Code:
        public class A
        {
            public virtual int Id { get; set; }
            public virtual A Next { get; set; }
        }
and then create 2 objects of type A called a1,a2
I set it up so that they point to one another, e.g.
a1.Next = a2;
a2.Next = a1;
I would then like to create mappings so that when I save one, the other is automatically saved via cascade in such a manner that their Next members are preserved. I have not been able to do this. Could somebody please give me an example of a mapping that can do this?
So far I have tried creating a hbm.xml which uses a many-to-one mapping. This does not work as a1.Next is not saved in the database. (Out of desperation I tried a one-to-one mapping but this results in an even more nonsensical setup, creating a table with nothing but an Id column)
example below:
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FluentNHibernate.Cfg;
using FluentNHibernate.Mapping;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
namespace hibernate.experiment
{
    [TestFixture]
    public class CircularDemo
    {
        [Test]
        public void CircularTest()
        {
            var file = "circulardemo.db";
            if (File.Exists(file))
                File.Delete(file);
            Configuration c = new Configuration();
            c.Properties["dialect"] = "NHibernate.Dialect.SQLiteDialect";
            c.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
            c.Properties["connection.driver_class"] = "NHibernate.Driver.SQLite20Driver";
            c.Properties["connection.connection_string"] = "Data Source=" + file + ";Version=3;";
            c.AddFile("hibernate.experiment.CircularDemo+A.hbm.xml");
            new SchemaExport(c).Create(true, true);
            var sFactory = c.BuildSessionFactory();
            using (var s = sFactory.OpenSession())
            {
                A a1 = new A();
                A a2 = new A();
                a1.Next = a2;
                a2.Next = a1;
                Assert.NotNull(a1.Next);
                Assert.NotNull(a2.Next);
                s.Save(a1);
            }
            using (var s = sFactory.OpenSession())
            {
                foreach (var a in s.CreateCriteria(typeof(A)).List<A>())
                    Assert.NotNull(a.Next);
            }
        }
        public class A
        {
            public virtual int Id { get; set; }
            public virtual A Next { get; set; }
        }
    }
}
hibernate.experiment.CircularDemo+A.hbm.xml file below:
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="">
  <class name="hibernate.experiment.CircularDemo+A, hibernate.experiment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`A`" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" type="Int32" column="Id">
      <generator class="identity" />
    </id>
    <many-to-one cascade="all" name="Next" column="Next_id" />
  </class>
</hibernate-mapping>
If someone could explain what I am doing wrong I would be grateful.