rmrs.persist
Class PersistentObject

java.lang.Object
  |
  +--rmrs.persist.PersistentObject

public class PersistentObject
extends java.lang.Object
implements java.lang.Cloneable

Any class needing persistence for its object must inherit from the class PersistentObject. To persist an object it needs a persistence broker assigned to it. A peristence broker is assigned to an object in either of two ways:

  1. when a new object is first saved to that broker with the method void save(PersistenceBroker broker),
  2. when an object is retrieved from a persistence broker. To save a previously retrieved object, just use the method void save() without arguments.

A persistence broker is statically assigned to each object. At this point, an object can not migrate from one broker to another, however, this could be made possible quite easily.

Note that persistence brokers are assigned to objects not to entire classes. This means, that the objects of one class can be distributed over multiple persistence brokers.

A class that inherits from PersistentObject only needs to obey to a few conventions, as described in the following checklist:

  1. Provide either a public default constructor (i.e. a constructor without arguments),

  2. or provide a static method without arguments that returns a new java object of the given class. Using that latter method is preferred since it can be private and thus protected from accidential abuse outside the business of perstistence.

  3. To check the consistency of a retireved object and to reset transient variables that were not stored, the persistent class should provide a method void notifyRestored(). The persistence broker will call this method when the object has been retrieved.

When an object is saved for the first time it will be assigned a unique object id. Currently that object id is unique only within the persistence broker, but (with only a few more work) it can be made unique accross all objects.

A persistent object can be in any of three principle "moods". This "mood" can not change throughout the life of a Java object.

  1. A real object represents a persistent object in a Java VM. Multiple JVMs can have the same persistent object checked out at the same time, but each persistent object can only occur once as a real object in any JVM. (Note: the concurrency is not currently checked and handled reliably. Needs more work.)

  2. A query example is a java object of a persistent class that is not in itself persistent, does not have an OID, and does not represent an individuum. Conversely, a query example represents an entire class (set) of objects that have are consistent with the specified field values.

  3. An object view is a java object without itself being persistent reflecting other persistent objects one at a time. An object view is like a mirror that can show different faces without being itself a face. Object views will be used to allow scanning through data base tables without incurring the high price of Java object creation. Not currently used.

Version:
$Id: PersistentObject.java,v 1.1 1999/12/06 19:25:44 schadow Exp SCHADOW_G $
Author:
Gunther Schadow

Field Summary
static int AUTO_SAVE
          object is supposed to be automatically saved upon finalization.
static int NEW
          indicates the object is brand new, never saved before.
static int OBJECT_VIEW
          indicates that object is an object view, whose values reflect the values of another real object.
static int QUERY_EXAMPLE
          indicates that object is a query example used in formulating queries.
static int REAL_OBJECT
          indicates that object is a real perisistent object, it can be saved and retrieved.
static int SAVEABLE
          object is a real object an not write protected.
 
Constructor Summary
protected PersistentObject()
          A constructor called automatically for any new persisten object created.
 
Method Summary
protected  java.lang.Object clone()
          Cloning becomes important to build convenient query examples (QE) and object views (OV).
 PersistentObject cloneQueryExample()
          Create a query example to query for all objects that are like this object.
protected  void finalize()
          This is for the auto save functionality, but finalize is not called at the end of the program, why? Is it not virtual?
 java.util.Date getCheckOutTime()
          Get accessor to check out time.
protected  int getFlags()
          Get accessor to the management bitset.
 java.util.Date getLastSaveTime()
          Get accessor to time the object was last saved time.
 OID getOID()
          Get accessor to OID field.
 PersistenceBroker getPersistenceBroker()
          Get currently assigned persistence broker.
 boolean isAutoSave()
          Predicate telling whether the object is supposed to be saved on finalization.
 boolean isNew()
          Predicate telling whether the object has never been saved.
 boolean isObjectView()
          Predicate telling whether the java object is an object view.
 boolean isQueryExample()
          Predicate telling whether the java object is a query example.
 boolean isRealObject()
          Predicate telling whether the java object is a real object.
 boolean isSaveable()
          Predicate telling whether the object can be saved.
protected  void notifyRestored()
          Call-back method to check the consistency of a retireved object and to reset transient variables that were not stored, the persistent class should overload this method if it maintains transient state.
protected  void prepareRestoring(PersistenceBroker pb, OID oid, int flags, java.util.Date cotime, java.util.Date lstime)
          The persistence broker calls this method shortly before retrieval to set the management field.
 ObjectSet query()
          Query for all objects that are like this query example.
 ObjectSet query(PersistenceBroker pb)
          Query for all objects that are like this query example.
 void save()
          Save an object with a previously assigned persistence broker.
 void save(PersistenceBroker pb)
          Save an object with a persistence broker.
 void setAutoSave(boolean v)
          Automatically save object in finalization.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

NEW

public static final int NEW
indicates the object is brand new, never saved before.

REAL_OBJECT

public static final int REAL_OBJECT
indicates that object is a real perisistent object, it can be saved and retrieved.

QUERY_EXAMPLE

public static final int QUERY_EXAMPLE
indicates that object is a query example used in formulating queries. The query method can be invoked only on a query example.

OBJECT_VIEW

public static final int OBJECT_VIEW
indicates that object is an object view, whose values reflect the values of another real object. Beware that object views may change their values dynamically. Object views are only used locally for scanning and searching operations.

SAVEABLE

public static final int SAVEABLE
object is a real object an not write protected.

AUTO_SAVE

public static final int AUTO_SAVE
object is supposed to be automatically saved upon finalization.
Constructor Detail

PersistentObject

protected PersistentObject()
A constructor called automatically for any new persisten object created. This is called for both, objects that are newly created by the applications and to be retrieved objects by the persistence broker. Therefore anything done here should make sense for both cases.
Method Detail

getOID

public OID getOID()
Get accessor to OID field. An oid is only assigned to real objects after being saved the first time (loaded objects obviously were saved before.) Object views have the oid value, of the object they currently reflect, but the object view itself has no identity.
Returns:
the oid of the object or null if no oid assigned.

getCheckOutTime

public java.util.Date getCheckOutTime()
Get accessor to check out time. Checkout time allows the detection of concurrent check outs. When an object is checked out the checkout time in the database is set. When an object is saved back and check out time has changed, we know that someone else uses this object. How is concurrency handled? For example, by allowing only read-only check-outs on an object that's already checked out.
Returns:
the check out time as a Date (or sql.Timestamp) object.

getLastSaveTime

public java.util.Date getLastSaveTime()
Get accessor to time the object was last saved time. Last saved time allows to tell whether an object has changed since it was last saved. Concurrency strategy needs more planning and implementation!

getFlags

protected int getFlags()
Get accessor to the management bitset. Interpret only using the predefined masks, better not use it at all.

getPersistenceBroker

public PersistenceBroker getPersistenceBroker()
Get currently assigned persistence broker.

isNew

public boolean isNew()
Predicate telling whether the object has never been saved.

isSaveable

public boolean isSaveable()
Predicate telling whether the object can be saved.

isAutoSave

public boolean isAutoSave()
Predicate telling whether the object is supposed to be saved on finalization.

isRealObject

public boolean isRealObject()
Predicate telling whether the java object is a real object.

isQueryExample

public boolean isQueryExample()
Predicate telling whether the java object is a query example.

isObjectView

public boolean isObjectView()
Predicate telling whether the java object is an object view.

setAutoSave

public void setAutoSave(boolean v)
Automatically save object in finalization.
Parameters:
v - true to turn on auto save, false to turn it off.

save

public void save(PersistenceBroker pb)
          throws PersistException
Save an object with a persistence broker. This method can only be used once for new objects that have never been saved before. The persistence broker automatically assigns an OID to a registrant and a registrant must not have a pre-assigned oid.
Parameters:
pb - a persistence broker that can store this kind of objects.

save

public void save()
          throws PersistException
Save an object with a previously assigned persistence broker. This method can only be used if the object has been saved before or was previously retrieved from a persistence broker.

notifyRestored

protected void notifyRestored()
Call-back method to check the consistency of a retireved object and to reset transient variables that were not stored, the persistent class should overload this method if it maintains transient state. The persistence broker will call this method when the object has been retrieved.

prepareRestoring

protected void prepareRestoring(PersistenceBroker pb,
                                OID oid,
                                int flags,
                                java.util.Date cotime,
                                java.util.Date lstime)
The persistence broker calls this method shortly before retrieval to set the management field. Few classes will want to overload this.

finalize

protected void finalize()
                 throws PersistException
This is for the auto save functionality, but finalize is not called at the end of the program, why? Is it not virtual?
Overrides:
finalize in class java.lang.Object

clone

protected java.lang.Object clone()
Cloning becomes important to build convenient query examples (QE) and object views (OV). QEs and OVs are Java objects of the same class as the objects queried for, but they are not the real objects themselves. The QE object is passed to a Broker's query method and eventually defines the SQL 'WHERE' clause. Results of a query are passed back in an OV. The OV is like a cursor and has a next method to skip to the next result record.

Cloning comes into place at three steps:

  1. a user can clone a real object to create a QE object. The user can then change some values and set other values to null and pass the QE object to a persistence broker's query method.

  2. the persistence broker will clone a QE object to create an OV object, which it returns to present the query results.

  3. the user can clone an OV object to create the real object currently represented by that OV.

This query by example feature is very intuitive and saves the programmer from dealing with lots of artificial query-criteria objects. It is also independent of SQL, i.e., it could work as well in an OODB.

What is arguably nice is that the user deals with one application class (e.g., Employee) and can use it to create real objects, QE objects and OV objects. This allows great uniformity since dealing with those objects is largely independent on their mood. (We call "mood" what distinguishes real objects from QE and QV.)

There is a slight risk, though, that may or may not turn out to be crucial. The programmer must never assign an OV object to other objects as if it where a real object, since an OV object changes its values farther down the road. Same is true for QE objects, but since a QE object is passed to the data base and not returned from it, the mistake to use it right away will occur less likely.

So, all persistent objects are cloneable, but the clone method is not directly used. Instead, the methods cloneQueryExample, cloneObjectView, and cloneRealObject are used.

Overrides:
clone in class java.lang.Object

cloneQueryExample

public PersistentObject cloneQueryExample()
Create a query example to query for all objects that are like this object. After cloning one would typically set some of the query example's fields to null in order to broaden the search. The clone is shallow, that is, assiciated objects are selected by OID. In the future, we'll allow complex query examples that let you retrieve object graph patterns.

query

public ObjectSet query(PersistenceBroker pb)
                throws PersistException
Query for all objects that are like this query example. Only allowed for query examples (not for real objects or object views.) The persistence broker can be reassigned to search matching objects on multiple brokers. This reassigns the persistence broker of the query example.
Parameters:
pb - a persistence broker

query

public ObjectSet query()
                throws PersistException
Query for all objects that are like this query example. Only allowed for query examples (not for real objects or object views.)