Transparent Activation

db4o activation framework

Since version 6.3, db4o provides an activation framework as described here.

However, this framework requires for each object to implement an additional interface plus an Activator field, and then call activate on the Activator when you need to access the content of the object.

Example

/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 
 public class SensorPanelTA /*must implement Activatable for TA*/implements Activatable {
 
   private Object _sensor;
 
   private SensorPanelTA _next;
 
   /*activator registered for this class*/
   transient Activator _activator;
   
   public SensorPanelTA() {
     // default constructor for instantiation
   }
 
   public SensorPanelTA(int value) {
     _sensor = new Integer(value);
   }
 
   /*Bind the class to the specified object container, create the activator*/
   public void bind(Activator activator) {
     if (null != _activator) {
       throw new IllegalStateException();
     }
     _activator = activator;
   }
 
   /*Call the registered activator to activate the next level,
    * the activator remembers the objects that were already 
    * activated and won't activate them twice. 
    */
   protected void activate() {
     if (_activator == null)
       return;
     _activator.activate();
   }
   
   public SensorPanelTA getNext() {
     /*activate direct members*/
     activate();
     return _next;
   }
   
   public Object getSensor() {
     /*activate direct members*/
     activate();
     return _sensor;
   }
   
   public String toString() {
     return "Sensor #" + getSensor();
   }
 }

Activation with Javassist

Javassist

"Javassist (Java programming assistant) is a load-time reflective system for Java."

Activation with Javassist

The Javassist based activation will use the built-in activation and make it transparent to objects. This extension replaces the default reflection classes and generates "extended" objects when necessary. Since Javassist is based on code generation, it has a very low impact on performances. The main cost is on the first activation/persistence on a class which generates the code for a proxy class.

Configuration

The @Activate annotation on any method will generate a callback that activates the object.

Limitations

Getters on objects cannot be final to enable activation.

Example

public class SensorPanelCTA {

  private Object _sensor;

  protected SensorPanelCTA _next;

  public SensorPanelCTA(int value) {
    _sensor = new Integer(value);
  }

  @Activate
  public SensorPanelCTA getNext() {
    return _next;
  }

  @Activate
  public Object getSensor() {
    return _sensor;
  }
  
  public void setSensor(Object val) {
    _sensor = val;
  }

}
public class CTActivationTest {

  private File tmpFile;

  public void createDB() {
    if (tmpFile != null)
      return;

    try {
      tmpFile = File.createTempFile("db4o", ".db");
      Configuration conf = Db4o.newConfiguration();
      conf.add(new CTASupport());
      ObjectContainer db = Db4o.openFile(conf, tmpFile.getAbsolutePath());
      System.out.println("creating db " + tmpFile.getAbsolutePath());
      SensorPanelCTA sensor = SensorPanelCTA.createList(15);
      db.set(sensor);
      db.commit();
      db.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

  }

  public void queryWithCGLIB() {
    createDB();    
    Configuration conf = configureTA();
    ObjectContainer db = Db4o.openFile(conf, tmpFile.getAbsolutePath());
    Query qr = db.query();
    qr.constrain(SensorPanelCTA.class);
    qr.descend("_sensor").constrain(new Integer(1));
    Collection<SensorPanelCTA> dbs = qr.execute();
    assertTrue(dbs.iterator().hasNext());
    // the next is loaded transparently
    SensorPanelCTA first = dbs.iterator().next();
    assertNotNull(first.getNext());
    db.close();
  }
  
}