-->
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.  [ 9 posts ] 
Author Message
 Post subject: Merge vs. Update
PostPosted: Thu Jun 05, 2008 5:44 pm 
Newbie

Joined: Tue Feb 26, 2008 1:17 pm
Posts: 9
I have a parent-child relationship that I want to delete children on (using delete-orphan). At the time of update, the parent is detached from the session, as are all the children. I want to remove a child from the collection, and am able to do this with merge(), but not with update(). My question is what is the difference between the two methods? When I use update(), I can not remove, but it will add new children. Why does update() not cascade changes for deletes on the detached instance?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 06, 2008 2:05 am 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
could you post your mapping file and the code snippet please!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 06, 2008 9:21 am 
Newbie

Joined: Tue Feb 26, 2008 1:17 pm
Posts: 9
A Party has a set of Emails:

Code:
<hibernate-mapping>
    <class name="model.common.Party" table="PARTY" schema="REBAR" lazy="false">
        <id name="partyId" type="java.lang.Long">
            <column name="PARTY_ID" precision="12" scale="0" />
            <generator class="sequence">
                <param name="sequence">PARTY_ID_SEQ</param>
            </generator>
        </id>
<set name="emails" cascade="all-delete-orphan" lazy="false" inverse="true">
            <key>
                <column name="PARTY_ID" precision="12" scale="0" not-null="true" />
            </key>
            <one-to-many class="model.common.Email" />
        </set>
    </class>
</hibernate-mapping>

<hibernate-mapping>
    <class name="model.common.Email" table="EMAIL" schema="REBAR">
        <id name="emailId" type="java.lang.Long">
            <column name="EMAIL_ID" precision="12" scale="0" />
            <generator class="sequence">
                <param name="sequence">EMAIL_ID_SEQ</param>
            </generator>
        </id>
         <many-to-one name="party" class="model.common.Party" fetch="select">
            <column name="PARTY_ID" precision="12" scale="0" />
        </many-to-one>
        <property name="current" type="true_false">
            <column name="IS_CURRENT" length="1" />
        </property>
        <property name="primary" type="true_false">
            <column name="IS_PRIMARY" length="1" />
        </property>
         <property name="usageType" type="string">
            <column name="USAGE_TYPE" length="18" />
        </property>
        <property name="emailAddress" type="string">
            <column name="EMAIL_ADDRESS" length="200" />
        </property>
    </class>
</hibernate-mapping>


Since it is detached and never has a party stored in the email, before I update (or merge), I set the party back into the email:

Code:
if (party.getEmails() != null) {
            for (Email email : party.getEmails()) {
                email.setParty(party);
            }
        }


In order to update I use Spring where this = HibernateDaoSupport:

Code:
this.getHibernateTemplate().update(party);


I also tried this, but it still didn't remove orphans. Only merge() did:

Code:
this.getSession.update(party);


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 06, 2008 9:35 am 
Regular
Regular

Joined: Wed Apr 09, 2008 10:28 am
Posts: 52
sounds strange i just know that you cant remove detached objects and ive read somewhere that when you use merge() it associates the object with a session. i don't know if update does this too but if not this would probably explain the behavoir. You don'T get any exception? log?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 06, 2008 12:17 pm 
Newbie

Joined: Tue Feb 26, 2008 1:17 pm
Posts: 9
Maybe this is a better way to put my question. Below are the API docs for the two methods. I just don't see why the cascade=all-delete-orphan does not work for detached instances when calling update(). So when update() says "Update the persistent instance with the identifer...", that is different than loading it into session? How can it update the persistent instance if it doesn't first load it into session?

update(Object obj)
Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to associated instances if the association is mapped with cascade="save-update".

merge(Object obj)
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".

PS...No exception in the log. Both methods work, just the cascading delete-orphan doesn't work for update(). The parent object is updated just fine using update(), and any children that do not have an ID are added to the database.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 09, 2008 3:04 pm 
Newbie

Joined: Tue Feb 26, 2008 1:17 pm
Posts: 9
Just thought I would give it one more try. Are there any other thoughts on this? Or maybe an expanded explanation of the API documentation for merge vs. update?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 09, 2008 3:51 pm 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Well, it never hurts to go right to the JavaDoc documentation:



http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Session.html#update(java.lang.String,%20java.lang.Object)

Quote:
merge

public Object merge(Object object)
throws HibernateException

Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".

The semantics of this method are defined by JSR-220.



Quote:
update

public void update(String entityName,
Object object)
throws HibernateException

Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to associated instances if the association is mapped with cascade="save-update".

Parameters:
object - a detached instance containing updated state
Throws:
HibernateException




A better understanding of detached instances, transient objects and persistent objects probably wouldn't hurt,either. Check out this little tutorial on How Hibernate Works to get a better understanding of how the Session uses and caches instances while it is open.

http://www.hiberbook.com/HiberBookWeb/learn.jsp?tutorial=07howhibernateworks

-Cameron McKenzie[/code]

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 1:31 pm 
Newbie

Joined: Tue Feb 26, 2008 1:17 pm
Posts: 9
Simply put, I will be using merge() to solve this problem. Thanks to all who took a look.

-K

PS...You can go to section 21.3 and 21.4 of this page to get a better idea of what I was trying to ask. It shows that you can add to the children as I stated, but fails to show me clearly why removing a child does not cascade when doing update(). http://www.hibernate.org/hib_docs/v3/reference/en/html/example-parentchild.html

You can also review Java Persistence with Hibernate (Bauer, King) pg. 409-414.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 1:49 pm 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Awesome. Thanks for the references!

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.