Transparent Persistence

Challenges

The main challenge to handle transparent persistence is the creation of objects. Objects are usually created using calls to the constructor and this creates a challenge for dynamically enhancing classes. [Comparison] details some differences between this approach and the instrumentation tools provided by db4o. The main advantage of proxy based persistence is that no build modifications are required, this allows to run tests in Eclipse or any other IDE without any changes whereas the instrumentation would require a special plugin and modifications of build scripts.

Comparison between TP and Proxy based persistence
Proxy Based TP Instrumentation based TP
Constructors cannot be used yes
Build no changes classes have to be instrumented
Testing no changes classes have to be instrumented
Persistence factories classes have to be instrumented
Granularity Customizable Classes

Dynamic Factories

Objects have to be created using factories. To make this easy, we require as little code as possible: one interface with one method that has arguments that match a constructor.

Factories must comply with the following requirements:

  • A Factory must be an interface with one method
  • The method must return the type that needs to be created
  • The method must have arguments that match one constructor in the class

Example without transparent persistence

TreeItem bug = new TreeItem();
bug.setName("bug");
db.store(bug);
TreeItem root = new TreeItem();
bug.addChild(root);
root.setParent(bug);
root.setName("root");
db.store(root);
With Transparent Persistence
public class TreeItem {
        private List<TreeItem> childs = null;
        private TreeItem parent = null;

        @Persist
        public void addChild(TreeItem it) {
                if (childs == null)
                        childs = new ArrayList4<TreeItem>();
                childs.add(it);
        }
        @Persist 
        void setParent(TreeItem parent) {
                this.parent = parent;
        }
        private TreeItem getParent() {
                return parent;
        }
}
TreeItemFactory treeFac = new PersistentFactories(db).createFactory(TreeItemFactory.class);
TreeItem bug = treeFac.createTreeItem(); // the instance is created and stored
TreeItem root = treeFac.createTreeItem();
bug.addChild(root);
root.setParent(bug);
public interface TreeItemFactory {
        
        public TreeItem createTreeItem();

}