Heres a list of some of the most common problems we get:

* bad unsaved-value mappings
* problems with cascade save for composite-id classes
* "an object with this id was already associated with the session"

It turns out that they can all be addressed by adding a new method
to the session. This method looks a little bit like saveOrUpdate()
except that instead of relying completely upon the guess made from
the unsaved-value mapping, it always hits the database to try and
load up the existing object before updating it (or grabs an already
loaded object from the session cache). The new state is then /copied/
onto the loaded object and the loaded object is returned to the user.
We never get the exception listed above, because we don't try to add
the given object to the cache. If no object is returned from the
database, we save the given object.

Cascade semantics for this operation are the same as for
saveOrUpdate().

This approach has two enormous disadvantages:

(1) it breaks == from the user's POV
(2) it is much less efficient than just doing an update

But, as long as we have both options, all is good.

(Actually, this is a bit of an improved implementation of what has
been proposed for JDO2.)

Gentlemen, I give you: saveOrUpdateCopy()

Yes, it is not the most inspired naming ever, but I can't think
of anything better. JDO2 will call this operation reattach() or
reassociate() ... which is an absolutely horrible choice, since
the only thing it does /not/ do is reattach/reassociate the
given instance with the session. (Unlike lock() or update(),
both of which /do/ perform reassociation.)

This is mainly provided to

(a) help out people who are trying to make composite-id stuff work
(b) solve problems for people who try to do this:

  Foo foo =.....;
  Foo oldFoo = session.get( Foo.class, foo.getId() );
  if (oldFoo!=null) doSomethingWithOldFoo(oldFoo);
  session.saveOrUpdate(foo); //ERROR!

Now they can just happily do:

  Foo foo =.....;
  Foo oldFoo = session.get( Foo.class, foo.getId() );
  if (oldFoo!=null) doSomethingWithOldFoo(oldFoo);
  foo = session.saveOrUpdateCopy(foo);

I think this is worth the effort. You can find it in CVS.

--
Gavin King
JBoss Group
+61 410534454
http://hibernate.org



-------------------------------------------------------
This SF.Net email sponsored by: ApacheCon 2003,
16-19 November in Las Vegas. Learn firsthand the latest
developments in Apache, PHP, Perl, XML, Java, MySQL,
WebDAV, and more! http://www.apachecon.com/
_______________________________________________
hibernate-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/hibernate-devel

Reply via email to