SimpleStore Users Guide

Table of Contents

 

About this Guide

The SimpleStore User Guide is intended to help bean providers get acquainted with Simplestore.
Thanks for choosing Simplestore!

What is SimpleStore ?

SimpleStore is customizable persistence framework. It defines interfaces for Transparent Persistence and provides reference implementation. It designed to store objects in Transactional resource like RDMS, but can be used with any kind of storage. It is two storage types in reference implementation: RDMS and BTree file from JDBM project. "Transparent" means no Query Language, Code Generation or Storage Specific API. Persistent Object doe's not extend any specific class and doe's not implement some interface from SimpleStore API. Users code can use it, but must not depend on it( Downcast ). It is recommended to "hide" PersistentManager and internal Transactions too. Use Facade and Factory design patterns to make your code clean. It is useful if you will decide to make your objects Distributed. See Apache's AltRMI for more information on Transparent Distribution implementation.

What can SimpleStore do for me ?

You can use it to implement persistency aspect in your web application, or object model, you can use it as service for your server like EOB or EJB (CMP,BMP). You can extend it and implement your persistence framework or for some like JDO. SimpleStore is Open Source and you can use it in commercial projects, see Apache license for details.

PersitenceManagerFactory

This interface is used to implement well known Factory design pattern it used to setup singleton PersitenceManager instanse.PersitenceManager is the most specific interface in your code:

     DBPersistenceManagerFactory factory = new DBPersistenceManagerFactory();
        factory.setDriver("org.hsqldb.jdbcDriver");
        factory.setUrl("jdbc:hsqldb:sample");
        factory.setUser("sa");
        factory.setPassword("");
        factory.setMaxConnections(1);
        factory.setMetaResource("org/apache/commons/simplestore/storage.xml");
      PersitenceManager  pm = factory.getPersistenceManager();
this example setups PersitenceManager to use RDMS as storage.

PersitenceManager

PersitenceManager is factory for your beans and transactions, Transaction is the last interface you need to know from SimpleStore if you not going to extend SimpleStore. You don't need to extend any specific Class or implement internal persistence interfaces, y ou don't need any code generator. Just design your object model, use interfaces and classes, SimpleStore will implement persistence aspect for you, but you still need some "Metadata" it is very trivial xml file, but it can be written using optional tags or generated later. Start to design beans:

 public abstract class Message{

        public MessageImpl(){}

        public void addReply( Message m ) {
          m.setSubmitted(new java.util.Date());
          m.setParent(this);
    }
        public int numberOfReplies() {
          return getReplies().size();
    }
     public abstract java.util.Collection getReplies();

     public abstract Date getSubmitted();

     public abstract void setSubmitted(Date v);

     public abstract String getContents();

     public abstract void setContents(String v); 

     public abstract String getEmail();

     public abstract void setEmail(String v); 

     public abstract String getName(); 

     public abstract void setName(String v);

     public abstract String getSubject(); 

     public abstract void setSubject(String v);

     public abstract void setParent( Message parent );

   }
 
This is persistent bean from Jakarta Velocity demo, it is recommended framework for web applications. All abstract methods are implemented by SimpleStore, PersitenceManager returns this implementation:
       PersitenceManager  pm = factory.getPersistenceManager();
       Transaction transaction = pm.getTransaction(); 

       transaction.begin();   

          Message parent = pm.findInstance(Message.class,parentOid);
          Message msg    = pm.createInstance(Message.class);           
                  msg.setSubject(subject);
                  msg.setEmail(email);
                  msg.setName(name);
                  msg.setContents(contents);
                  parent.addReplay(msg);

       transaction.commit();
 
At last you will need some metadata it helps simplestore to implement your beans:
   <?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE storage> 
      <storage>
        <mclass  id="Message" name="MESSAGE">
          <field id="parent" name="parent">
              <reference mclass="Message"/>
          </field>
          <field id="replies">
          <reference mclass="Message" field="parent"/> 
          </field>
        </mclass>
     </storage>
  

Transaction

SimpleStore supports only atomic persistence operations, All operations must be in transaction context:

    Transaction transaction = pm.getTransaction(); 
        transaction.begin();
        //..........................
        //     operations 
        //..........................
       transaction.commit();// or transaction.rollback();
It is fragment from SimpleStore test, it demonstrates rollback:
         transaction.begin();
            TestPersistentClassType object = (TestPersistentClassType) i.next();
            String val = object.getStrVal();
            object.setStrVal( i + "");
            transaction.rollback();

            transaction.begin();
               assertEquals("After rollback ", val, object.getStrVal());
             transaction.commit();
 

Identity

All persistent objects have OID, it is recomended to use Serializable Object for OID, reference implementaion uses java.lang.Long and default (Random) generator. It is single persistent instance in SimpleStore with concreate OID.
Next always evaluates to true :

     
    if( pm.findInstance(Message.class, pm.getOID( msg ) ) == msg ){

       ..................................
  }

OID is managed by framework and it is no way to change it for persistent object. SimpleStore overrides int hashCode() and boolean equals(Object obj) methods in class Object.
Next always evaluates to true :
    if( pm.findInstance(Message.class, pm.getOID( msg ) ).equals( msg ) ){

       ..................................
  }

State

It is to methods in PersistenceManager for persitent object state. boolean isNew(Object p) returns true if object is returned from Object createInstance(Class cls) in current transaction. boolean isDeleted(Object p) returns true if object is deleted in any transacton. Use void removeInstance(Object p) to delete persistent object. Managed methods throws java.lang.IllegalStateException if deleted object is accessed inside or outside transaction.

Cache

Cache is transparent for SimpleStore user. It used for optimizations and reachability management, but it is "invisible" in code. It is recomended to use default implementation.

Validation

Metadada is used to define validation rules. Validator is custom object see javadoc for more information on Validator interface, and sample NotNull validator implementation. Persistent object implementation throws ValidationException if registread validator returns false for managed property value.

        <field id='propertyName' name='fieldName'>
             <validator id='ClassName'/>
        </field>
 

Security

Custom interceptors used for security checks. SimpleStore doe's not define any specific Permissions and doe's no security checks. Read more about customizations see Developers Guide .

Related Projects


Copyright © 1999-2002, Apache Software Foundation