Hibernate version:
2.1.6
Mapping documents:
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="test">
<class name="Customer" table="cust">
<id name="id" type="int" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="name">
<column name="name"/>
</property>
<property name="address">
<column name="address"/>
</property>
<set name="orders" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="cust_id"/>
<one-to-many class="Order"/>
</set>
</class>
<class name="Order" table="cust_order">
<id name="id" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="productName" column="product_name"/>
<property name="memo" column="memo"/>
<many-to-one name="Customer" column="cust_id"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
session = HibernateUtil.currentSession();
transaction = session.beginTransaction();
customer = (Customer) session.load(Customer.class, new Integer(1));
// This will access all Order objects and call their toString()
// method; all Order objects are then loaded
print(customer.getOrders());
transaction.commit();
HibernateUtil.closeSession();
print("==================");
session = HibernateUtil.currentSession();
transaction = session.beginTransaction();
customer.setAddress("changed address 1");
session.update(customer);
transaction.commit();
Full stack trace of any exception that occurs:This question is not exception related.
Name and version of the database you are using:MySQL 4.0.18
Debug level Hibernate log excerpt:Code:
Hibernate: select customer0_.id as id0_, customer0_.name as name0_, customer0_.address as address0_ from cust customer0_ where customer0_.id=?
Hibernate: select orders0_.cust_id as cust_id__, orders0_.id as id__, orders0_.id as id0_, orders0_.product_name as product_2_0_, orders0_.memo as memo0_ from cust_order orders0_ where orders0_.cust_id=?
[Order: id=4, memo=testtesttestan orphaned record, productName=Printer, Order: id=3, memo=yet another order, productName=Chair, Order: id=1, memo=new order, productName=Lamp, Order: id=2, memo=another order, productName=Desk]
==================
Hibernate: update cust set name=?, address=? where id=?
Hibernate: update cust_order set product_name=?, memo=? where id=?
Hibernate: update cust_order set product_name=?, memo=? where id=?
Hibernate: update cust_order set product_name=?, memo=? where id=?
Hibernate: update cust_order set product_name=?, memo=? where id=?
I have a Customer object which is associated with a Set of Order objects. In the mapping Customer's "set" entry has attributes inverse="false", lazy="true", and cascade="all-delete-orphan".
When I update a Customer field that is unrelated to the association (Customer.address), I really want to JUST update the underlying cust table, because neither Customer-Order association nor any Customer object referred by the association is updated/dirty. However, as the log shows, Hibernate still generates SQL updates for the Order objects (cust_order table.) How can I avoid this without giving up on the convenience of cascade "all" or "save-update"? I understand these cascade options mean Hibernate will traverse the association and make persistent the Order objects, but is it possible for Hibernate to know that none of the Order objects actually changed and avoid the unnecessary updates? It can be a lot of useless updates!
Another observation: if I do not force the Order set within Customer object to be loaded (via a toString() method that calls toString() on each Order object contained in the set), then Hibernate actually does not genenerate the extra update statements.