From: Sven W. <s_...@in...> - 2002-03-21 23:15:36
|
> >> (1) Does the "state" of the transient instance include it's id? Since > >> hibernate allows the Session to track id's, I'm thinking, on the face > >> of it, the answer is "no". > > > Hmm, this raises the question: How do I find the old record in the > > database ? So, the answer is "yes" because ID is usually a property that > is > > stored inside the transient/persisted object. > > What I was really getting at here was: Do we use the id held _inside_ the > object, or do we let the application provide it? Should it be: > > persistentObject = Session.update(transientObject); > > or: > > persistentObject = Session.update(id, transientObject); > > or should we allow both forms? I don't know but if I have to choose I would only use the first one because we're persisting objects to a database and everything in the database has to be identifyable. "Normal" objects in c++/java/smalltalk do not have an ID but tuples in a (relational) db must have one. > >> (2) Does the "state" of the transient instance include it's version > number? > >> I'm thinking the answer is to this would be "yes". > > > Yes, a version number would really help. But we have to be aware that > having > > a single version number does _not_ guarantee serializability (there are > > phantom reads and non repeatable reads). Ok, it is possible to set the > > transaction isolation in the jdbc driver to serializable but then the > question > > appears why having version numbers at all. > > I'm assuming that the most typical use of this functionality would be to > load a persistent object in one transaction (the first session) and then > update it in a second (transaction and session). ie. It would be used with > what we are calling "long transactions with versioning". Obviously if this > is not the case and we are doing everything in one transaction, versioning > is not such an important issue. *agreed* > I'm not suggesting that we disable the functionality for non-versioned > objects, merely asking wether we use the version number held by the > transient instance, or the version number held by the existing persistent > instance when we update. It seems clear that it should be the version > in the transient instance. For versioned objects using the transient instance makes sense. > If I call > > Session.update(transientObject); > Object persistentObject = Session.load( transientObject.getID() ); > > Does transientObject == persistentObject ? > > I'm thinking *no*. Other persistent objects loaded by the session might > already have references to the object with the given id and it would be > a very difficult problem to swap all their references to point to > transientInstance. Even then, the application might have pointers to > persistentObject. Hence, I favor the form: > > persistentObject = Session.update(transientObject); > > which returns another instance of the class, with the same id and > persistent > state as transientObject. I do not see a problem with this approach. transientObject == persiententObject --> false transientObject.equals (persistentObject) --> true But I do not know whether update is the right function name for such a functionality with these semantics. I would not expect to get a new object back after an db update. Please let me add that update() has to be efficient in terms of DB access because it will be called very often if stateless session beans are used. This implies that we need some kind of hints a programmer may provide. e.g. Object update (Object instance, boolean deferredCheck) : do not reload the persistent instance from database but instead check versions at the end of the transaction on database update/delete: if updateCount == 0 --> rollback Object updateNonVersioned (Object instance, boolean isDirty) : ! the programmer has to do the concurrency checking ! isDirty=true -> issue an db update isDirty=false -> just put it in the session This might me useful if there are custom concurrency checking methods. |