net.sf.spif.persistence
Class StorePersister

java.lang.Object
  |
  +--net.sf.spif.StoreChain
        |
        +--net.sf.spif.persistence.StorePersister

public class StorePersister
extends StoreChain

Automatic storage of model objects

The StorePersister is a Store chain which stores to and fetches from a relational storage by automatically matching classes to db tables.

For instance If you wish to persist a Person having a PersonId, a name and an Address, and the address in turn contains a street and a city. All you need to do is create the db tables PERSON(ID,NAME) and ADDRESS(ID,STREET,CITY) and plug this class into you store chain.

You don't even need to match tables exactly to classes, the single table PERSON(ID,NAME,ADDRESSSTREET,ADDRESSCITY) would work just as fine as the two above.

No manual mapping or code generation is needed. When a new type is accessed or store runtime, the object and db tables are matched. The match is cached to be used for later use, which makes the overhead of of negible.

Getting the job done without making a mapping requires that some rules must be followed followed. Generally, tables are named the same as classes and fields the same as columns. This makes the StorePersister a bad choice for most applications developing to legacy or corporate-wide dbs. For projects developing db schemas with the code, however, there is no reason to use different names, and no reason to have humans do work perfectly suited for a machine.

The persistence rules

The goal of the StorePersister is to be as good at making a mapping as a human with absolutely no domain knowledge. Furthermore, is understands edit bubbles as described in Model Centric Rules.

In practice, this means that most objects will map to the db with no human intervention, while some special cases will require special handling, either in form of additional methods in the domain objects or as special classes adding or preparing information to the objects being persisted. When reading the limitations below, keep in mind that using the StorePersister is not a all-or-nothing choice - adding a filtering store chain in front of this which sends the problematis requests to some other persistence mechanism works is straightforward. Also, as you won't invest in any tool-specific mapping, you won't have loosed anything if you find the special cases are becoming the norm and chooses to abandon this class.

These are the rules followed. Keep in mind that a log of the matches done will be produced (as info to a java.util.logging.Logger named by this class name). So it may just be faster to try and see if it does what you want than to read and understand these rules.

There will not be uncontrolled backwards-incompatible changes to these rules. I.e. restrictions may disappear without notice, but not the other way around.

The current limitations to be aware of:

The three first of these limitations will be addressed in the next major release of Spif.

I am sure you can live with these limitations and follow the lead of the lazy!

This store will not currently propagate store chain requests (though this may well be implemented later).

Version:
$Id: StorePersister.java,v 1.5 2003/02/13 22:13:44 bratseth Exp $
Author:
Jon S Bratseth

Field Summary
protected static java.util.logging.Logger log
           
 
Fields inherited from class net.sf.spif.StoreChain
chained
 
Constructor Summary
StorePersister(java.lang.String dataSourceName)
          Creates an instance
 
Method Summary
protected  TypePersister createTypePersister(java.lang.Class type, java.sql.Connection connection)
          Creates a type persister for a given id class.
 java.lang.Object get(Id id, boolean writable)
          Returns an object from the store.
 Id put(Id id, java.lang.Object object)
          Puts an object in the store.
protected  boolean reentrantAccess()
          This defends agains cases where a getter invocation on a store object causes a new access for a store object.
 boolean remove(Id id)
          Removes an object.
 
Methods inherited from class net.sf.spif.StoreChain
clear, equals, getChained, getChained, getChained, hashCode, setChained
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

protected static java.util.logging.Logger log
Constructor Detail

StorePersister

public StorePersister(java.lang.String dataSourceName)
Creates an instance

Parameters:
dataSourceName - the name of the dataSource to obtain db connections from. This class gets jndi connections from the InitialContextFactory which you'll have to initialize first.
Method Detail

get

public java.lang.Object get(Id id,
                            boolean writable)
Description copied from class: StoreChain

Returns an object from the store.

This default implementation just forwards to the chained. for (optional) use by subclasses.

Overrides:
get in class StoreChain
Parameters:
id - the id of the object to return
Returns:
the object, or null if the object could not be retrieved or if the input id was null

put

public Id put(Id id,
              java.lang.Object object)
Description copied from class: StoreChain

Puts an object in the store. The objects may be new, or previously acquired by getting writeable. It is an error to attempt to put an existing object not previously acquired by getting writeable.

This default implementation just forwards to the chained. for (optional) use by subclasses.

Overrides:
put in class StoreChain
Parameters:
id - the id of the object to put. May be null
object - the object to put. May be null
Returns:
the id of this object. This will usually be (and is in this default implementation) the input id, unless the given id is null and there is an id generating service on the store chain

remove

public boolean remove(Id id)
Description copied from class: StoreChain

Removes an object. Does nothign if the object does not exist.

This default implementation just forwards to the chained. for (optional) use by subclasses.

Overrides:
remove in class StoreChain
Parameters:
id - the id of the object to remove
Returns:
true if the object did not exists

reentrantAccess

protected boolean reentrantAccess()
This defends agains cases where a getter invocation on a store object causes a new access for a store object. Such implicit accesses should be avoided (but I admit I do it myself sometimes). Anyway, this check allows us to operate correctly on implicit accesses anyway by returning null if we access the store when we are allready in the store.


createTypePersister

protected TypePersister createTypePersister(java.lang.Class type,
                                            java.sql.Connection connection)
                                     throws java.sql.SQLException
Creates a type persister for a given id class. Override to use custom persisters for certain types.

java.sql.SQLException


Spif 1.01 (2003-04-03). http://spif.sf.net