title: Why does hibernate permit the update of a parent table although update="false" is provided to the many-to-one relationship?
body: <p>I created a simple case for testing and I don't get the expected behavior. 
  <strong>I am interested why hibernate chooses to update the parent table (Country) although I provide update="false" attribute to the many-to-one relationship (in the Address.hbm.xml)?</strong>  </p>
  
  <p>The DDLs:</p>
  
  <pre><code>CREATE TABLE Country (
    `id` smallint NOT NULL auto_increment,
    `name` varchar(100) NOT NULL,
    PRIMARY KEY (`id`)
  ) TYPE=InnoDB AUTO_INCREMENT=0;
  CREATE TABLE Address (
    `id` bigint NOT NULL auto_increment,
    `firstName` varchar(100) NOT NULL,
    `lastName` varchar(100) NOT NULL,
    `countryId` smallint NOT NULL,
    PRIMARY KEY (`id`),
    FOREIGN KEY (countryId)
     REFERENCES Country(id)
     ON UPDATE CASCADE ON DELETE RESTRICT
  ) TYPE=InnoDB AUTO_INCREMENT=0;
  </code></pre>
  
  <p>The hibernate xmls:</p>
  
  <pre><code>&lt;class name="Country" table="Country" lazy="false"&gt;
      &lt;id name="id" column="id" type="integer"&gt;
          &lt;generator class="native" /&gt;
      &lt;/id&gt;
      &lt;property name="name" type="string" not-null="true" length="100"/&gt;
  &lt;/class&gt;
  &lt;class name="Address" table="Address" &gt;
      &lt;id name="id" column="id" type="long" unsaved-value="-1"&gt;
          &lt;generator class="native" /&gt;
      &lt;/id&gt;
      &lt;property name="addressFirstName" column="firstName" type="string" not-null="true" length="100"/&gt;
      &lt;property name="addressLastName" column="lastName" type="string" not-null="true" length="100"/&gt;
      &lt;!-- Country is parent table, Address is child table (holds the FK countryId).
          From MySQL:
          CASCADE: Update the row from the parent table and automatically update the matching rows in the child table.
          RESTRICT: Rejects the delete operation for the parent table.
          From hibernate:
          1. cascade (optional): specifies which operations should be cascaded from the parent object to the associated object.
          2. update, insert (optional - defaults to true): specifies that the mapped columns should be included in SQL UPDATE 
          and/or INSERT statements. Setting both to false allows a pure "derived" association whose value is initialized 
          from another property that maps to the same column(s), or by a trigger or other application.
       --&gt;
      &lt;many-to-one name="country" class="Country" column="countryId" 
          not-null="true" cascade="persist,merge,save-update"  update="false" /&gt;
      &lt;many-to-one name="state" class="State" column="stateId" 
          cascade="persist,merge,save-update" update="false" /&gt;
  &lt;/class&gt;
  </code></pre>
  
  <p>My Country table has one row (id=1):</p>
  
  <pre><code>INSERT INTO Country (name) VALUES ("United States");
  </code></pre>
  
  <p>If I do following:</p>
  
  <pre><code>Country country = getCountryFrom("US");
  Address address = new Address();
  address.setAddressFirstName("Deksa");
  address.setAddressLastName("Jakim");
  country.setName("Slovenia");
  address.setCountry(country);
  address.setId(-1);
  saveAddress(address);
  session.saveOrUpdate(address);
  </code></pre>
  
  <p>I expect that I have one new row inserted in the Address table, but I also get an update on the Country table - the only row, the name of the country becomes Slovenia, instead of staying United States (expected behavior &lt;= update="false"):</p>
  
  <pre><code>Hibernate: select country0_.id as id6_, country0_.name as name6_ from Country country0_ where country0_.stringId='US'
  Hibernate: insert into Address (firstName, lastName, countryId) values (?, ?, ?)
  Hibernate: update Country set name=? where id=?
  </code></pre>
  
  <p><strong>So why does hibernate update the parent table when instructed not to?</strong></p>
  
  <p>Kind regards,<br>
  Despot</p>
  
  <p>Edit: Shortly after writing this post I realized that I am confusing the DB's cascade with the hibernate's cascade and that solved all my problems.<br>
  The thing is the following: Hibernate clearly says: </p>
  
  <blockquote>
    <p>update, insert (optional - defaults to
    true): specifies that the mapped
    columns should be included in SQL
    UPDATE  and/or INSERT statements.
    Setting both to false allows a pure
    "derived" association whose value is
    initialized from another property that
    maps to the same column(s), or by a
    trigger or other application.</p>
  </blockquote>
  
  <p>. This means that when using update="false" on the country property (on the countryId), I say to hibernate you cannot do UPDATE Address SET firstName="x", lastName="y", <strong>countryId=123</strong> where condition; Only do an update without the countryId.<br>
  Than I saw that the DB's ON UPDATE CASCADE refers to the parent table (Country) - if the Country was updated, than update the child table (the countryId column in Address table). Contrary to what I thought hibernate's update would do, I realized that by providing cascade="save-update", I say to hibebernate, whatever values you have for the Country object in the Address object update them in it's own Country table. So the solution was to have cascade="persist,merge" without the save-update part!</p>