Note that there are some explanatory texts on larger screens.

plurals
  1. PONhibernate Cascade=none is not working as expected
    text
    copied!<p>I have two classes, Vendor and contact. Vendor is a parent of Contact. There's a one-to-many relationship between Vendor and Contact. I have set the cascading relationship between Vendor and Company as none. This means (at least to me) when I change a Contact for a Vendor and save the Vendor, this saving action should NOT cascade to the Contact and therefore, any changes I make to Contact should not persist to the database.</p> <p><strong>However, this is not the case</strong>. When I change the FirstName of a Contact and save its parent, the saving action is cascaded to Contact. For example using below's test function, I see a Contact with the FirstName = "This_new_first_name_should_not_be_saved". Initially, I did not expect to see this change persist to the database.</p> <p>Am I simply misunderstanding how cascade works or is there something wrong with my code?</p> <p>Test.cs</p> <pre><code>[Test] public void RemoveManyToOneAssociation() { var container = BuildContainer(); var vendorRepo = container.Resolve&lt;Repository&lt;Vendor&gt;&gt;(); //Get respository var contactRepo = container.Resolve&lt;Repository&lt;Contact&gt;&gt;(); //Get repository var vendor = vendorRepo.FirstOrDefault(); var contact = vendor.Contacts.FirstOrDefault(); contact.FirstName = "This_new_first_name_should_not_be_saved"; vendor.Contacts.Remove(contact); vendorRepo.Save(vendor); //The saving action above should not cascade to contacts because we have set cascade to "none" } </code></pre> <p><strong>Vendor.hbm.xml</strong></p> <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt; &lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataAccess" namespace="DataAccess"&gt; &lt;class name="Vendor"&gt; &lt;id name="Id" type="int" unsaved-value="0"&gt; &lt;generator class="hilo" /&gt; &lt;/id&gt; &lt;property name="VendorName" /&gt; &lt;set name="Contacts" inverse="true" cascade="none"&gt; &lt;key column="VendorID" /&gt; &lt;one-to-many class="Contact"/&gt; &lt;/set&gt; &lt;many-to-one name="Company" column="CompanyID"&gt;&lt;/many-to-one&gt; &lt;/class&gt; &lt;/hibernate-mapping&gt; </code></pre> <p><strong>Contact.hbm.xml</strong></p> <pre><code> &lt;?xml version="1.0" encoding="utf-8" ?&gt; &lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataAccess" namespace="DataAccess"&gt; &lt;class name="Contact"&gt; &lt;id name="Id" type="int"&gt; &lt;generator class="hilo" /&gt; &lt;/id&gt; &lt;property name="FirstName" /&gt; &lt;property name="LastName" /&gt; &lt;many-to-one name="Vendor" class="Vendor" column="VendorID"&gt;&lt;/many-to-one&gt; &lt;/class&gt; &lt;/hibernate-mapping&gt; </code></pre> <p><strong>Vendor.cs</strong></p> <pre><code>public class Vendor : Entity&lt;int&gt; { public Vendor() { } public Vendor(string name) { VendorName = name; } public virtual string VendorName { set; get; } public virtual ISet&lt;Contact&gt; Contacts { set; get; } public virtual Company Company { set; get; } public virtual void CopyTo(Vendor target) { target.VendorName = VendorName; target.Company = Company; } } </code></pre> <p><strong>Contact.cs</strong></p> <pre><code>public class Contact : Entity&lt;int&gt; { public Contact() { //it's not the best practice to initialize virtual properties in constructor but we're controlling //the inheritance in this so doing this should be fine // http://stackoverflow.com/a/469577/89605 FirstName = ""; LastName = ""; } public Contact(string firstName, string lastName) { FirstName = firstName; LastName = lastName; } public virtual string FirstName { set; get; } public virtual string LastName { set; get; } public virtual Vendor Vendor { set; get; } public virtual void CopyTo(Contact contact) { contact.FirstName = FirstName; contact.LastName = LastName; } } </code></pre> <p><strong>Update</strong> *<em>Repository.cs</em>*</p> <pre><code>public class Repository&lt;T&gt; where T : class { private ISession _session; public Repository(ISession session) { _session = session; } public virtual T GetById(int id) { return _session.Get&lt;T&gt;(id); } public virtual T LoadById(int id) { return _session.Load&lt;T&gt;(id); } public virtual List&lt;T&gt; GetAll() { return _session.Query&lt;T&gt;().ToList(); } public virtual T FirstOrDefault() { return _session.Query&lt;T&gt;().FirstOrDefault(); } public virtual void Save(T entity) { using (ITransaction _transaction = _session.BeginTransaction()) { _session.Save(entity); _transaction.Commit(); } } public virtual void Delete(T entity) { using (ITransaction _transaction = _session.BeginTransaction()) { _session.Delete(entity); _transaction.Commit(); } } } </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