-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: avoid updating collection when updating an object
PostPosted: Fri Sep 10, 2004 12:01 am 
Newbie

Joined: Thu Sep 09, 2004 7:54 pm
Posts: 4
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 10, 2004 4:52 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
change
Code:
            customer.setAddress("changed address 1");
            session.update(customer);


to
Code:
session.lock(customer);         
customer.setAddress("changed address 1");

//no session.update() 
//commit....

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 10, 2004 1:09 pm 
Newbie

Joined: Thu Sep 09, 2004 7:54 pm
Posts: 4
Thanks anthony -- it works (with LockMode.NONE.)

Still, is it correct understanding that session.update(Object) will always generate SQL update statements for the Object passed in and all objects in collection associated with cascade="save-update" or cascade="all" options even if none of the objects in collection or the collection itself isn't updated?

anthony wrote:
change
Code:
            customer.setAddress("changed address 1");
            session.update(customer);


to
Code:
session.lock(customer);         
customer.setAddress("changed address 1");

//no session.update() 
//commit....


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.