Mnemosyne

Object Database for Java

Mnemosyne is an object database for Java. Using Mnemosyne you can persist any java object directly and easily. Aspect Oriented Programming (AOP) is utilized to make the process of persistence completely transparent. There is no need to set up complex object-relational mappings, and there is no need for your business objects to implement or extend a particular interface or class.

Mnemosyne works by "persistence by reachability". The graph of all objects reachable from a particular "persistent root object" is automatically made persistent. This persistent object graph is held entirely in memory (although object paging support is planned). As transactions execute, they are logged to a transaction journel on disk. Regular "snapshots" of the entire persistent graph are also taken. When the system reloads, the latest snapshot is read, and subsequent transactions are then re-applied to that snapshot to bring the system up to date.

Mnemosyne also ensures full ACID (atomic, consistent, isolated, durable) properties for all transactions. This important database property ensures that your persistent data is always in a valid state. ACID transactions are acheived in Mnemosyne by object level versioning and locking of persistent objects. Once again, this is completely transparent to the application developer.

Mnemosyne is Free Software. It is licensed under the Apache 2.0 license, which allows the use of Mnemosyne in both commercial and open source projects.

An Example

Here is a quick example to demostrate how easy it is to use Mnemosyne. First you must define the business objects that you wish to be persistent:

    public class Customer {
        private String name;
        private String address;

        public String getName() { return name; }
        public void setName(String value) { name = value; }
        public String getAddress() { return address; }
        public void setAddress(String value) { address = value; }
    }
                

As you can see, there is nothing special about this class. There is no special base class that you must extend, or no interface that you must implement.

Next you must configure your aspect oriented system (at present only AspectWerkz is supported) to introduce the Mnemosyne aspects into your Customer class. How you do this depends on the AOP engine you are using. Aspectwerkz allows you to compile the aspects in at build time, or have them dynamically woven at runtime. Here is a sample aspectwerkz configuration file for our example:

<aspectwerkz>
  <system id="mnemosyne-example">

    <aspect class="mnemosyne.aop.aspectwerkz.PersistenceAspect"
            deployment-model="perInstance">

      <introduce class="mnemosyne.aop.aspectwerkz.AspectwerkzPersistenceMixin$PersistenceMixinImpl"
                 deployment-model="perInstance"
                 bind-to="within(Customer)"/>

      <advice name="persistenceAdvice"
              type="around"
              bind-to="execution(* Customer.*(..))"/>
    </aspect>

  </system>
</aspectwerkz>
                

This configuration introduces a special Mnemosyne "mixin" class into the Customer class, and binds some advice to every method in the Customer class. It is this advice that takes care of managing the persistence of instances of Customer.

Finally here is some code that creates a new customer, makes it persistent, updates it, then removes the customer from the persistent store.

    // Create the persistent system. This is the main interface into Mnemosyne.
    PersistentSystem system = PersistentSystemFactory.createPersistentSystem();

    // Create a new Customer
    Customer customer = new Customer();
    customer.setName("Fred Flintstone");
    customer.setAddress("100 Gravel Rd, Bedrock");

    // Make this customer persistent.  We do this by adding it to the persistent root
    // with an identifier (which we can use later to retrieve it).
    system.beginTransaction();
    system.setPersistentRoot("thecustomer", customer);
    system.endTransaction();

    // The customer object is now persistent.  In future executions it can
    // be retrieved by "system.getPersistentRoot("thecustomer");

    // Now lets update the customer's address.  During a Mnemosyne transaction
    // you can update any persistent object. Mnemosyne takes care of making the
    // changes persistent in an ACID manner.
    system.beginTransaction();
    customer.setAddress("20 Neanderthal Way, Bedrock");
    system.endTransaction();

    // Finally remove the customer from the persistent store
    system.beginTransaction();
    system.removePersistentRoot("thecustomer");
    system.endTransaction();
                

And thats all there is to it!