title: NHibernate cascading save
body: <p>This is trying to insert null into Comment.BlogArticleID.</p>
  
  <p>The following GenericADOException appeared:
  "could not insert: [NHibernate__OneToMany.BO.Comment][SQL: INSERT INTO Comment (Name) VALUES (?); select SCOPE_IDENTITY()]"</p>
  
  <p>The following Inner-Exception appeared: 
  "Cannot insert the value NULL into column 'BlogArticleID', table 'Relationships_Test_OneToMany.dbo.Comment'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."</p>
  
  <p><strong>I need a unidirectional mapping.</strong> The answer provided yet is talking about bi-directional mapping.</p>
  
  <p>Does NHibernate cascade save works with native ID generator?</p>
  
  <h2>DB tables:</h2>
  
  <p>BlogArticle{ID, Name}, where in case of ID, Identitity=true.</p>
  
  <p>Comment{ID, Name, BlogArticleID}, where in case of ID, Identitity=true.</p>
  
  <h2>Comment.hbm.xml</h2>
  
  <pre><code>&lt;hibernate-mapping
    xmlns="urn:nhibernate-mapping-2.2"
    assembly="NHibernate__OneToMany.BO"
    namespace="NHibernate__OneToMany.BO"
    default-access="property"&gt;
  
    &lt;class name="Comment" table="Comment"&gt;
      &lt;id name="ID"&gt;
        &lt;generator class="native" /&gt;
      &lt;/id&gt;
  
      &lt;property name="Name" /&gt;
    &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  
  public class Comment
      {
          private int _id;
          public virtual int ID
          {
              get { return _id; }
              set { _id = value; }
          }
  
          public Comment()
          {
          }
  
          public Comment(string name)
          {
              this._name = name;
          }
  
          private string _name;
          public virtual string Name
          {
              get { return _name; }
              set { _name = value; }
          }   
      }
  </code></pre>
  
  <h2>BlogArticle.hbm.xml</h2>
  
  <pre><code>&lt;hibernate-mapping 
    xmlns="urn:nhibernate-mapping-2.2"
    namespace="NHibernate__OneToMany.BO"
    assembly="NHibernate__OneToMany.BO"
    default-access="property"&gt;
    &lt;class name="BlogArticle"  table="BlogArticle"&gt;
      &lt;id name="ID"&gt;
        &lt;generator class="native" /&gt;
      &lt;/id&gt;
  
      &lt;property name="Name" column="Name" /&gt;
  
      &lt;bag name="Comments" cascade="all" &gt;
        &lt;key column="BlogArticleID" /&gt;
        &lt;one-to-many class="Comment" /&gt;
      &lt;/bag&gt;
    &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  
  
  public class BlogArticle
      {
          private int _id;
          public virtual int ID
          {
              get { return _id; }
              set { _id = value; }
          }
  
          private string _name;
          public virtual string Name
          {
              get { return _name; }
              set { _name = value; }
          }
  
          private IList _depts;
          public virtual IList Comments
          {
              get { return _depts; }
              set { _depts = value; }
          }   
      }
  </code></pre>
  
  <h2>Main</h2>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          BlogArticle ba = new BlogArticle();
          ba.Name = "Humanity";
          ba.Comments = new List&lt;Comment&gt;();
          ba.Comments.Add(new Comment("Comm1"));
          ba.Comments.Add(new Comment("Comm2"));
          ba.Comments.Add(new Comment("Comm3"));
  
          Repository&lt;BlogArticle&gt; rep = new Repository&lt;BlogArticle&gt;();
          rep.Save(ba);
      }
  }
  </code></pre>
  
  <h2>Repository</h2>
  
  <pre><code>public class Repository&lt;T&gt; : IRepository&lt;T&gt;
      {
          ISession _session;
  
          public Repository()
          {
              _session = SessionFactoryManager.SessionFactory.OpenSession();
          }
  
          private void Commit()
          {
              if (_session.Transaction.IsActive)
              {
                  _session.Transaction.Commit();
              }
          }
  
          private void Rollback()
          {
              if (_session.Transaction.IsActive)
              {
                  _session.Transaction.Rollback();
                  //_session.Clear();
              }
          }
  
          private void BeginTransaction()
          {
              _session.BeginTransaction();
          }
  
          public void Save(T obj)
          {
              try
              {
                  this.BeginTransaction();
  
                  _session.Save(obj);                
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }            
          }
  
          void IRepository&lt;T&gt;.Save(IList&lt;T&gt; objs)
          {
              try
              {
                  this.BeginTransaction();
  
                  for (Int32 I = 0; I &lt; objs.Count; ++I)
                  {
                      _session.Save(objs[I]);
                  }
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }
          }
  
          void IRepository&lt;T&gt;.Update(T obj)
          {
              try
              {
                  this.BeginTransaction();
  
                  _session.Update(obj);
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }
          }
  
          void IRepository&lt;T&gt;.Update(IList&lt;T&gt; objs)
          {
              try
              {
                  this.BeginTransaction();
  
                  for (Int32 I = 0; I &lt; objs.Count; ++I)
                  {
                      _session.Update(objs[I]);
                  }
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }
          }
  
          void IRepository&lt;T&gt;.Delete(T obj)
          {
              try
              {
                  this.BeginTransaction();
  
                  _session.Delete(obj);
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }  
          }
  
          void IRepository&lt;T&gt;.Delete(IList&lt;T&gt; objs)
          {
              try
              {
                  this.BeginTransaction();
  
                  for (Int32 I = 0; I &lt; objs.Count; ++I)
                  {
                      _session.Delete(objs[I]);
                  }
  
                  this.Commit();
              }
              catch (Exception ex)
              {
                  this.Rollback();
  
                  throw ex;
              }
          }
  
          T IRepository&lt;T&gt;.Load&lt;T&gt;(object id)
          {
              return _session.Load&lt;T&gt;(id);
          }
  
          public IList&lt;T&gt; Get&lt;T&gt;(int pageIndex, int pageSize)
          {
              ICriteria criteria = _session.CreateCriteria(typeof(T));
              criteria.SetFirstResult(pageIndex * pageSize);
              if (pageSize &gt; 0)
              {
                  criteria.SetMaxResults(pageSize);
              }
              return criteria.List&lt;T&gt;();
          }
  
          public T Get&lt;T&gt;(object id)
          {
              return _session.Get&lt;T&gt;(id);
          }
  
          public IList&lt;T&gt; Get&lt;T&gt;()
          {
              return Get&lt;T&gt;(0, 0);
          }
  
          public IList&lt;T&gt; Get&lt;T&gt;(string propertyName, bool Ascending)
          {
              Order cr1 = new Order(propertyName, Ascending);
  
              IList&lt;T&gt; objsResult = _session.CreateCriteria(typeof(T)).AddOrder(cr1).List&lt;T&gt;();
  
              return objsResult;
          }
  
          public IList&lt;T&gt; Find&lt;T&gt;(IList&lt;string&gt; strs)
          {
              System.Collections.Generic.IList&lt;NHibernate.Criterion.ICriterion&gt; objs = new System.Collections.Generic.List&lt;ICriterion&gt;();
              foreach (string s in strs)
              {
                  NHibernate.Criterion.ICriterion cr1 = NHibernate.Criterion.Expression.Sql(s);
                  objs.Add(cr1);
              }
              ICriteria criteria = _session.CreateCriteria(typeof(T));
              foreach (ICriterion rest in objs)
                  _session.CreateCriteria(typeof(T)).Add(rest);
  
              criteria.SetFirstResult(0);
              return criteria.List&lt;T&gt;();
          }
  
          public void Detach(T item)
          {
              _session.Evict(item);
          }        
      }
  </code></pre>