|Principles | Requirements | Architecture | Features | Rules | Storable objects | String x Text|
JSO works as a persitence layer, encapsulating O-R mapping and database access, so that you don't have to worry about it. You should only code your classes (according to some rules) and let JSO do the rest. Persistence code in your application should be limited to calls to JSO's API, requesting the storage or the retrieval of objects.
You don't need to specify how your object model will be mapped to the database. JSO will inspect your classes in runtime (through Java's reflection API) and store them transparently. You don't even have to know how the database is modeled. In fact, you should not access the database directly, only through JSO. This runtime mapping forbids JSO accessing legacy data.
Before running your application you should create an empty database and grant permissions to a specific user. This database and user will be passed to JSO, through configuration (properties) files, which will initialize the database upon startup. After that, persistence services become available to the application. As your application request those services, storable classes are inspected and their definitions are stored in the database. Also, new tables are created to house their instances.
JSO's major goal is to provide persistence to Java objects in relational databases, acting as persistence layer and handling the problem known as "impedance mismatch". This layer should exempt application developers from implementing persistence code (like SQL statements) or specifying mapping metadata (like XML descriptors). Some requirements were defined for this layer:
To be used with JSO, relational databases must fulfill some requirements:
The persistence layer implemented by JSO is divided in two main modules:
net.sf.jso.StorageController) has a central role in the layer. It coordinates concurrent persistence operations and provides some specific services like: object identification, storable classes schema, concurrency control, notification of persistence operations and garbage collections. The controller must be the first module started.
net.sf.jso.StorageManager) is the interface between the application and the layer. The application requests persistence services directly to the manager, which in turn accesses the database and communicates to the controller. The manager must always connect to a controller and register itself.
Many kinds of configurations may be obtained with this architecture. The simplest one consists of the application program, the controller, the manager ant the database running on the same computer, with the first three running on the same Java virtual machine. This configuration is considered to be a local one, because the communication between the manager and the controller is made through local calls.
A more complex configuration could be obtained running the database and the controller in one node of a network and programs and managers in other nodes. This configuration is considered to be distributed, because the managers communicate to the controller through remote calls (RMI).
The many possible configurations are defined through a "storage
net.sf.jso.StorageEnvironment). This environment
has the ability to start and stop local and distributed application programs,
connecting the managers to the controller.
When a distributed configuration is used the environment creates a "home" to the controller and registers it in the RMI registry of the node. The remote reference to the home may be acquired by a name specified by the developer. The remote reference to the controller may be acquired through the home, after an authentication process. The authentication consists of the validation of a user name and a password, also specified by the developer.
The fulfillment of the requirements and the use of the architecture discussed above allow JSO to offer the following features:
JSO offers a great level of freedom to developers for the implementation of storable classes. In spite of that, some rules apply:
net.sf.jso.Storableor be one of the following:
net.sf.jso.Storableinterface is merely a marker and has no fields or methods, like the
Storableclass must have a public void constructor.
Storableclass must not have its qualified name started by
jso(case insensitive) and must not have the character '
Storableclass must not be
Storableclasses may be any of the Java primitive types or a reference to any of the classes listed in item 1.
volatilewill not be stored.
Storableclass must not have any fields named
Basically, storable objects are all instances of
classes and all classes listed in the first rule (as seen
in the previous topic.
Storable classes (and objects), writen by
the developer, may also use additional features: object metadata, class
metadata and callback methods.
Besides its own value (values of fields), a storable object also has
storage metadata. This metadata represents information about the storage
process of an object. This information may be used by the application for
Storable classes my declare a field called
jsoMetadata, of type
and that field will be updated every time the storable object suffer the
action of the storage manager. Through the
interface the developer may get the manager which performed the last
persistence operation on the object, object's identification (OID) and
if the object is a summary object.
A summary object is an object that has been retrieved from the database with only part of its value, more specifically only with the value of its summary fields. These fields may be specified through class metadata (as we will see below) and can be considered as a "projection" of the object's field set. The definition of these fields is optional and the lack of it makes the summary of the object equal to the complete set of fields. Nevertheless, using this feature may be very usefull. For example, when displaying the result of a query usually a list containing only some of the classe's fields is shown to the user. The fields shown in the list may be defined as the summary fields. The queries may then use summary objects as results to save resources.
To specify the summary fields, and other "storable" characteristics, of a
class, the developer may use class metadata. The first time a
Storable class is presented to JSO it is inspected and some
information is obtained and stored in the database, for later use. At this
point an opportunity is given to the developer to supply more information
about how the class should be stored or used. A
may implement the static method
parameters or throws clauses) that returns an object of the type
net.sf.jso.schema.StorableClassMetadata. When a class is
inspected this method is called (if it exists) and its result is used to
inform JSO about more class' characteristcs.
StorableClassMetadata class allows the developer inform
Storableobjects are not collected unless the developer says so.
net.sf.jso.schema.StorableIndex) may be created to inform JSO to create indices on class' fields. Otherwise no indices are created.
Storable objects may be aware of persistence events
(operations). Three callback methods may be declared in the
jsoPreStore()is called by JSO before an object is stored.
jsoPostRetrieve()is called after an object is retrieved.
jsoPreDelete()is called before an object is deleted from the database.
String x Text
In Java the
java.lang.String class is commonly used to
store strings of many sizes, from simple words to long texts. Storing strings
in a database, nevertheless, requires some distinguishment. The storage cost
of arbitrarily long strings is inevitably higher than that of short
In order to provide means for the developer making such distinguishment
JSO offers the class
net.sf.jso.text.Text. Short strings
(containing up to 255 characters) should be represented by the
String class while long strings should be represented by the
Strings are stored in the database as
columns of the
VARCHAR JDBC type while
stored as columns of the
LONGVARCHAR JDBC type.
Text class works in a similar way to the
String class. It is also immutable and offers a subset of the
String class interface. The use of the concatenation operator
(+) is not possible though.