[Objectbridge-developers] Intelligent update
Brought to you by:
thma
From: Thomas M. <tho...@ho...> - 2000-11-05 11:18:02
|
Hi all here is a discussion about intelligent updates I hat with Bill: >> [BILL:] I *think* that to do this [Intelligent Update] will require >> some cooperation on the part of >> the user. > > > [THOMAS:] I aggree! There are approaches that use a preprocessor to > identify setters in the user code to generate the necessary > state-management in some OODB's. At least POET works this way. but > using a preprocessor does not fit well into the java world, I think. > >> The least intrusive way that I can think of to do this is for >> the persistable object to 1) contain some sort of StateManager >> object, which we provide; >> 2) update that StateManager object any time a setXXX method is executed >> on the persistable object. > > > I've included my latest snapshot. You will find a working example for > using the "ODMG-Server" in ojb.examples.server.App. > Studying my code will show you that all access to persistent object > has to be within a Transaction. > The TransactionImpl is responsible for tracking which persistable > objects have been newly created, loaded from the RDBMS or have been > touched by any setter-methods. > This is necessary for the transaction in order to do the right thing > with each persistable object on commit or rollback. > To accomplish this tracking the TransactionImpl maintains a hashtable > with objects (namely their identity hash) as keys and > ModificationState-objects as values. > This is very close to your suggestion of a StateManager per each > object. Only difference: I would prefer to not keep the StateManager > within the object, but in a hash table. One of my design goals is to > keep coupling of user code and our framework at a minimum ! > > My ModificationStates applies two design patterns: State and Command. > Here comes the State pattern: > When you start with reading an object from the RDBMS (as in > ojb.examples.server.Article::getArticleByPk(...)) your resulting > object will be marked with the state StateOldClean (Old = already in > RDBMS, Clean = unmodified). > All setters have to call method markModified() which results in a call > to TransactionImpl::markModified(object) where the state-transition > method ModificationState::markDirty() is called to return the > resulting new Modification state of our object. In this example the > State will change to StateOldDirty. See StateOldClean::markDirty(). > > Here comes Command: > When it comes to commiting or aborting the transaction, each objects > ModificationState is used to execute the proper action for each object. > some examples: > if an old object is clean there's no use of writing it to the DB on > commit(). But if it is marked OldDirty we need an UPDATE ! > if a newly created object has been marked for deletion, there's no use > of executing a DELETE on commit(), as the object is not stored in the > DB yet. > All new objects that have not been marked for deletion need an > INSERT-statement on commit. > On transaction commit the ModificationState::commit() is excuted for > each state in the transactions ObjectStateTable. As class > ModificationState is abstract, the semantics of commiting and aborting > a given state is defined in the concrete state classes. > >> >> I've attached two source files wich illustrate my thinking on this; both >> of them are in the ojb.examples.broker package on my machine: >> 1) StateManager.java -- initialized with the number of fields in the >> containing object, then uses bitmasking to keep track of the state of >> each of these fields; also has a boolean isModified() method that >> returns true if at least one field has been modified, or false if no >> modifications were made (use in tx manager?); > > > I think we can add your StateManager functionality (tracking which > fields have been modified) to my ModificationState class. > The algorithm is elegant and much faster than all my java reflection > stuff. > the markModified-Method needs a parameter that reaches fieldname or id > to the ModificationState. > >> 2) GranularUpdateTest.java -- has several fields that would be mapped to >> db columns; contains a StateManager object; each setXXX accessor method >> calls StateManager.updateState( field id number ); contains sample test >> code in the main method. >> >> I mention in comments in the code that perhaps the FieldDescriptor id, >> which is the same as the field id that the setXXX methods need to pass >> to the StateManager, could be looked up in the xml repository ... > > > Yes there's a method FieldDescriptor::getColNo() which returns the id > from the xml-file. > >> >> My idea is this: we can still persist arbitrary objects, but they will >> have to use the old style update (writing all instance variables to the >> db); > > > Very important point! The original PersistenceBroker should be kept as > generic as possible. > >> however, if someone wants to simply include the StateManager object >> and the updateState calls in their accessors, we can intelligently >> construct an update statement on only those fields that have been >> modified. > > > Exactly, TransactionImpl has to track all modifications of objects and > thus has all relevant knowledge to generate intelligent SQL code. > If you have a look at PersistenceBrokerImpl::store(Object) you will > see how "stupid" this generic approach is when we want to use it from > our server: > It creates and executes a select statement to check whether the object > is in the RDBMS already, in order to decide whether INSERT or UPDATE > is needed. > Our server knows if an object is already in the DB by a look at its > ModificationState: if its a StateOldXXX we just need an UPDATE. > And by including your tracking of field modification we can generate > very lean "SET FIELD = VALUE" clauses. > >> Caveat: this is all off the top of my head this morning, so if this does >> not mesh with the direction you have in mind, I'll gladly withdraw the >> idea ;-> > > > I think we have similar ideas how to address this update thing. Of > course you could not know that I was working on related things in the > server package already. > >> I've done Swing gui coding, and did produce a gui to help with an O/R >> mapping package at a previous employer. That package didn't use xml, >> but I'd be interested in trying to come up with something for this. > > > Your experience might be very helpful here ! > >> If >> someone else who loves gui coding joins the project, though , I wouldn't >> object to letting him/her do it ... > > > Same for me... > But maybe its to early to address this gui tool. In my opinion we have > to concentrate on the basic concepts first. Maybe there will still be > a lot of changes to the repository format during the process. I think > we can shift this task to one of the late stages of our project. > regards, Thomas > |