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.
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 |
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:
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);
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(); }