-->
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: How to update() a detached instance loaded indirectly
PostPosted: Tue Jul 13, 2004 12:24 am 
Beginner
Beginner

Joined: Thu Jun 24, 2004 1:04 pm
Posts: 35
Location: Minnesota - USA
Given...

1) A detached object from a previous session that I wish to update().
2) Various business logic validations which must be run (queries, etc.) which may cause the session to contain an object loaded with the same id as from (1). References to these objects are transient, I don't use them beyond the life of the validations. I have no intent of doing update() on the query results.
3) Calling update() on the object from (1) throws NonUniqueObjectException.

How do I deal with this? I've seen the saveOrUpdateCopy() method, jeez that's a bit too much a kitchen sink kinda method than I like to use. I don't even use saveOrUpdate(), if you don't know if you want to create the object or modify the object, you've got larger problems IMO. ;) Our persistence manager layer has 2 methods, insert() and update() that map to Hibernates save() and update() methods. I'd like to keep it simple.

Also, I read this original thread by Gavin, to help me understand what saveOrUpdateCopy() does http://www.mail-archive.com/hibernate-d ... 02795.html

I was hoping for a simple updateCopy(), without the load it from the database behaviour? Is that capability there and I missed it? Lacking that I was going to trying using Session.contains() and implement my own detection logic and decide how I wanted to deal with the copy issue. However, it does not return true for my detached object when the other instance is in the session. Is there another means I can use to determine if a session contains an object w/ and id, other than load()/get() that will not go to the database if the object is not in the session?

I considered trying to catch NonUniqueObjectException and deal with it then, but I've not done that as I've been told not to reuse the Session after a HibernateException has occurred. Inconsistent internal state, etc.

Which primitives operations on the Session can I use to deal with this in the fashion I need, and not have to rely on OOTB saveOrUpdateCopy() and that lot?

I'm going to try evict() before I do update() just to avoid this for now, I believe that should do the trick. Only because I need something functional for tomorrow. I don't see that as a long term solution however.

Just found this while searching as well http://www.hibernate.org/117.html#A23 , maybe evict() is the correct way to go? Kinda does make, since what I'm thinking I want to say is "screw the copy in the session, update the one I'm going to give you here". My only concern might be possible unknown side-effects when cascade is being used.

If anyone can shed more light... Thanks in advance.

--gus


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 13, 2004 3:40 am 
Beginner
Beginner

Joined: Thu Jun 24, 2004 1:04 pm
Posts: 35
Location: Minnesota - USA
Ugh, evict() doesn't seem to work with the detached object. I need to evict the object referenced within the session itself. But I can't get that object without calling load()/get() and hitting the database (very bad in the normal case when the object is not in the session), just so I can evict it. Tad circular ! ;)

Ideas?

Simpliest approach would be for evict(Object) to use the ID if it cannot do by Object == (persume it is that, because these objects implement hbm2java hashCode()/equals()). Other approaches might require Session API changes. I still liking the idea of updateCopy() w/o a DB select hit.

--gus


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 1:21 pm 
Beginner
Beginner

Joined: Thu Jun 24, 2004 1:04 pm
Posts: 35
Location: Minnesota - USA
Any thoughts?

Original posting was while I was pulling an all-nighter, so not many folks would've been able to see it before it got pushed to the bottom.

My temporary workaround was for this one use-case to do a load() by ID and then evict() the result, the subsequent update() of the detached object then succeeds. This is just a stopgap, until I can find an acceptable solution.

--gus


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 1:28 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
Our persistence manager layer has 2 methods, insert() and update() that map to Hibernates save() and update() methods. I'd like to keep it simple.

session.update(obj) doesn't mean update row in database but update the session with the given object, that is different.

What about using two sessions? the first to do your business validation, when you can conclude with this validation, close this session, obtain a new one, attache your detached object, flush and commit ?

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


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 1:52 pm 
Beginner
Beginner

Joined: Thu Jun 24, 2004 1:04 pm
Posts: 35
Location: Minnesota - USA
Ok, I understand what you're saying about the meaning of save()/update(). I think perhaps persistence manager insert()/update() methods should map to both map to saveOrUpdate().

Hmm, a 2nd session would be one means of making the problem, but I'm not certain I can find a clear delineation for when the 1st would end and the 2nd would begin. I believe no matter what point I choose, it would still be possible for the issue to arise in the 2nd session (for none business validation reasons let say).

I think I could live with saveOrUpdateCopy() if only it would not go to the database (as per Gavin's descripton of how it works and the Session API). The performance implications are horrible (we're using optimistic locking via <version>).

I still cannot understand why this version wants to do that, when the others do not. Does it have to do with consistently breaking == ? I'd think that could be accomplished via a copy/duplicate without hitting the db.

Thanks for the feedbak. I'll keep pondering.

--gus


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 2:44 pm 
Regular
Regular

Joined: Mon Jun 14, 2004 1:42 pm
Posts: 80
Location: Brazil
I was thinking that
sess.get(clazz,pk,LockMode.NONE)
avoided database fetch. But it don't :(
even if my class is proxy enabled, it stills go to the database.
Is there no way to just check if an object (by his PK, not by == contains) is associated with the cache? like getEntity(key) ?Something like:

Code:
// ObClass = the class of the obj
// obj =the Object you want to update
// myPk = Primary key of obj

// replace ".get" with a way to just check if the session has this object
// without going to database! like the private sess.getEntity(key)

Object old = sess.get(persistClass,myPk,LockMode.NONE);
if (old!=null)
  sess.evict(old)
sess.update(obj);
 

2 sessions will bring the concept of n session - 1 user interaction, what is a bad design...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 16, 2004 8:19 am 
Beginner
Beginner

Joined: Thu Jun 24, 2004 1:04 pm
Posts: 35
Location: Minnesota - USA
Yes, being able to determine if an id is in the session could be useful. However, in my case I use cascade, so it makes it a bit more difficult as I'd have to recurse...

At this point, my plan is one of two things:

1) Make certain there really is the lack of an API to determine if an object with a given id is in the Session without going to the database. If I'm wrong, then use it, otherwise add one. Then implement a cascading save() operation in my persistence manager that uses that API to lookup the object in the session and copy values onto it and then save(), or if not in the session do a object copy and an save() the copy (knowing it's not in the session currently).

2) Or, implement a version of saveOrUpdateCopy() that does not have DB hit semantics.

I'll explore (2) first I think, potential to be easiest of the two to implement. Also give me a chance to understand more about how Hibernate works, and I can always submit as a patch back to the project if I'm successful.

Will be a while 'til I get a chance to work on this, other things I need to finish first.

--gus


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.