-->
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.  [ 7 posts ] 
Author Message
 Post subject: session.saveOrUpdate vs. session.saveOrUpdateCopy
PostPosted: Mon Mar 29, 2004 10:48 pm 
Beginner
Beginner

Joined: Tue Aug 26, 2003 6:24 pm
Posts: 45
hi folks -
I'm using session.saveOrUpdateCopy(), to update certain fields in entities, which is working fine, except in a particular situation with cascade="all-delete-orphan" on a collection of entities.

the basic setup is:
Entity e1 has a reference to another entity e2.
e2 has a reference to e3

e3 has a cascade="all-delete-orphan" collection (Set) of e2

In our system, I would like to, within a single session:
- create e1 (i.e. first time it is stored)
- access the e3 entity using e1.getE2().getE3().
- update the e3 entity using saveOrUpdateCopy(e3)
- ---perform flush here---


What happens is that e3's collection of e2 is scheduled for deletion, which fails because e1 has a fk to e2. (and it shouldn't be deleted in the first place)

It works fine if:
- I use a separate session to save e3
- I use saveOrUpdate() instead of saveOrUpdateCopy() to update e3
- I use cascade="all" instead of "all-delete-orphan"

I traced this down to SessionImpl.doCopy() which does not provide a copy of the collection of e2 during saveOrUpdateCopy(e3) - with "all-delete-orphan", this causes the session to think I removed the elements in the collection.

Any ideas on why this might be happening?
Do I need to flush before I can start navigating the object graph?

thanks
tyson


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 30, 2004 3:49 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Please submit a very simple, runnable test case to jira - I don't quite understand your explanation, but it sounds like it might be something worth checking out.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 30, 2004 11:16 pm 
Beginner
Beginner

Joined: Tue Aug 26, 2003 6:24 pm
Posts: 45
I posted HB-862

in further testing, I also noticed that:

The fk failure occurs when:
- entities at top of hierarchy are saved
- entity at bottom of hierarchy is saved
- the session is closed
- new session is opened
- the saved entity is retrieved
- the save entity's parent is retrieved
- that entity's parnet is retrieved and updated

However, if I close the session immediately after the "top" entities are saved, I instead get a:
Code:
net.sf.hibernate.HibernateException: You may not dereference a collection with cascade="all-delete-orphan"

when updating the topmost parent as above.

more details in the jira issue...

thanks for any advice

tyson


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 31, 2004 7:25 pm 
Beginner
Beginner

Joined: Tue Aug 26, 2003 6:24 pm
Posts: 45
I was able to modify one of the test cases to produce this behavior - I added this comment to the jira issue.

Is there some reason that this *should* be illegal to do?

thanks for any info
tyson


To summarize how to reproduce it - this is loosely based on the FooBarTest hibernate test file:

modify the following test subjects:
- One.hbm.xml - add cascade="all-delete-orphan" for the "manies" set
- Baz.java - add a Many properties:
private Many many;
public Many getMany() {
return many;
}

public void setMany(Many many){
this.many = many;
}

and its mapping in Baz.hbm.xml:
<many-to-one name="many" column="many_key" class="org.hibernate.test.Many"/>


now use this test method:

public void testAutosaveChildren() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
//begin create a new One and its Manies
Many many = new Many();
Many many2 = new Many();

Set manies = new HashSet();
manies.add(many);
manies.add(many2);
One one= new One();

many.setOne(one);
many2.setOne(one);
one.setManies(manies);

s.save(many);
s.save(many2);
s.save(one);
//done creating One and Manies


//if we close the session here, and start a new session - the baz.getMany().getOne().manies collection
//is never init'd in the copy part of saveOrUpdateCopy()
//thus, the collection is deleted since the cascade="all-delete-orphan"
t.commit();
s.close();

s = openSession();
t = s.beginTransaction();

//load the Many we want to associate with our new Baz
Many bazMany = (Many)s.load(Many.class, many.getKey());
Baz baz = new Baz();
baz.setMany(bazMany);
s.save(baz);


//update baz.getMany().getOne()
One bazOne = baz.getMany().getOne();
bazOne.setValue("a new value for One!");

//if we use saveOrUpdate(bazOne), the update proceeds without deleting the baz.getMany().getOne().manies collection
s.saveOrUpdateCopy(bazOne);
// s.saveOrUpdate(bazOne);


s.flush();
t.commit();
s.close();
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 31, 2004 8:09 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Your code makes absolutely no sense at all.

Why do you saveOrUpdateCopy() the bazOne?? You just retrieved it from the db! It is already associated with the session.

Anyway, I see the cause - its true that there is a "bug", overlooked since we don't ever expect anyone to do something so silly.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 31, 2004 8:32 pm 
Beginner
Beginner

Joined: Tue Aug 26, 2003 6:24 pm
Posts: 45
Quote:
Why do you saveOrUpdateCopy() the bazOne?? You just retrieved it from the db! It is already associated with the session.


yep, its silly. The short story is that the majority of the controller interface is used for storing objects arriving from the view layer which are not connected to a session. SaveOrUpdateCopy has helped alleviate extra updates when data is not changed.

To avoid confusion with "which method should I use to save?" questions all of our updates are handled this way.

I'll try to revise it to always use saveOrUpdate instead of saveOrUpdateCopy, and see what happens

Thanks
tyson


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 31, 2004 9:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Well, anyway, the problem is fixed in CVS.

Still, lots of unnecessary calls to saveOrUpdateCopy() sounds like bad design.


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