RMRS/persist providing seamless object-relational persistence for your Java business objects.

Copyright © 1999, Regenstrief Institute for Health Care. All rights reserved.

Written by Gunther Schadow.

Release 1.0 - 12/6/1999 -- dedicated to Saint Nikolaus
This is an early release of the persistence broker. It works for me so far, but it is not yet robust, especially regarding concurrency and features implemented. I don't have alpha and beta release stages, but consider this alpha. THIS SOFTWARE IS PROVIDED AS IS, WITH NO WARRANTY WHATSOEVER, EXPRESS OR IMPLIED. DO NOT USE FOR MISSION CRITICAL DATA UNTIL YOU HAVE REVIEWED AND TESTED THE CODE.

How to use RMRS/persist

Please note: this package will only work for JDK 1.2, not for 1.1.x. This package works similarily seamlessly as java object serialization (JOS). In JDK 1.1, JOS heaviliy depended on native methods in the JVM, so Sun could do tricks that the normal user can't do. As of JDK 1.2 users can set and get fields of other objects, overriding accessibility constraints (package, protected, private.) That's the reason why this can not work on JDK 1.1. Sorry (it's bad for me too, but JDK 1.2 will soon be widely available on Unices too (Linux, FreeBSD.)

Every class whose instances are to be persistent must inherit from the class PersistentObject. Every persistent object has the methods:

void save(PersistenceBroker)
and
void save()
The PersistenceBroker is an interface with the user method
PersistentObject load(java.lang.Class, OID oid)
and soon some query (by example) methods. A preliminary and limited implementation of
ObjectSet PersistentObject.query()
and
ObjectSet PersistentObject.query(PersistenceBroker pb)
is now avaialable.

With RMRS/persist you can define the mapping of java classes to tables and java fields to columns in the data base (dictionary, two simple tables ps_class and ps_field.) For field mapping you can choose between the following kinds

direct
object is written into the db field, typical for primitives
inline
a composite object is inlined into the container table useful for composite values without identity (e.g. numeric interval (low/high), measurement (value/unit) etc.)
reference to-one
the object id (OID) of the associated object is written into the db field. An additional flag CASCADE_SAVE allows you to always save the associated object automatically.
reference to-many
the object id (OID) of this object is written into the forreign key field of each of the associated objects and, depending on the CASCADE_SAVE flag, the other objects are saved too.
The PersistenceBroker interface comes in two implementations right now
RelationalBroker
for MySQL, or HypersonicSQL and all that
ObjectRelationalBroker
for PostgreSQL
In addition I may add two XML brokers, an indexed XML file broker (GDBM) and a sequential XML file broker ... but I'm still mentally recovering from too much XML and too little data bases.

The nice thing about the RMRS/persist package is that the client objects don't have to have any special interface (like in COBRA.)  Rather, just like JOS, any field can be stored and retrieved from the data base without a special accessor method, and even if it's private.  The only requirement is that the field is defined in the data dictionary.  If a non-transient field is not in the dictionary, you get a warning but it still continues. The only stuff that persistent objects may want to implement is a special static constructor method so that the default constructor can be private. And a call-back method

void notifyRestored()
that is called by the broker when a persistent object awakes from it's sleep (to recalculate transient values, etc.) So, RMRS/persist it's very seamless.

For to-many associations the multiple distal objects must be kept in an ObjectSet. An ObjectSet is like a Vector that allows on-demand object loading. The ObjectSet may contain either OIDs or Objects.  Before an element of ObjectSet is returned an OID is resolved into an object. This implements a limited way to do on-demand loading, that is, load objects into memory only when needed.

The best way to get started with this is have a look into the test subdirectory. You will find one test scenario that implements inheritance, inlining, to-one, and to-many mappings. Including the data base initialization. Tested with HypersonicSQL, PostgreSQL, and MySQL (where there is a minor bug.)

I'm hoping that some other pair of eyes and hands might whant to check the concurrency behavior of this package (which I am currently not too concerned with) The goal is to make it thread safe on the Java side and concurrency-safe on the DB side.

On to Java generated API documentation.

See example source code.

Download