GoChaCha
  • Home
  • Cookbook
  • Docs
  • License
  • Contact
Download
Getting Started

One ObjectBox, one Object:

TestObject testObject = new TestObject();
ObjectBox objectBox = new ObjectBox(testObject);
objectBox.setField("doubleField", "1234.5");

Your object must have setters and getters for the fields you want to set and, in general, be a bean.

Any fields which are complex types must have default no-arg constructors if you’d like to be able to set their fields and have the ObjectBox construct them for you:

TestObject testObject = new TestObject();
ObjectBox objectBox = new ObjectBox(testObject);

String testString = "This is a test";
objectBox.setField("testSubObject.subStringField", testString);

Method Caching

Using reflection to call methods is, by and large, pretty fast. Looking up methods is, as a rule, pretty slow. Because of this GoChaCha provides a MethodCache.

The MethodCache itself isn’t particularly exciting; it’s a POJO. It doesn’t use a bizarre thread local singleton, or any other kind of singleton for that matter.

Working on the basis that you know how to manage state better than a library does for your particular application, you are responsible for passing the MethodCache object around from place to place, making new ones and generally follow a happy life. Indeed you could choose not to deal with them at all, in which case each ObjectBox will create its own which will live for the lifespan of the ObjectBox which contains it.

It can, however, be quite a bit faster to share the MethodCache around so that the lookup of getter and setter methods only happen once.

As an example, sharing the MethodCache for many many ObjectBoxes:

MethodCache methodCache = new MethodCache();

for(int i=0;i<100000;i++) {
 MyBean myBean = new MyBean();
 ObjectBox objectBox = new ObjectBox(myBean, methodCache);

 objectBox.setField("intValue","123456");
 objectBox.setField("doubleValue","123.456");
 objectBox.setField("longValue","123456");
 objectBox.setField("floatValue","123.456");
 objectBox.setField("shortValue","123");
 objectBox.setField("stringValue","string");
}

Takes roughly half the time of:

for(int i=0;i<100000;i++) {
 MyBean myBean = new MyBean();
 ObjectBox objectBox = new ObjectBox(myBean);

 objectBox.setField("intValue","123456");
 objectBox.setField("doubleValue","123.456");
 objectBox.setField("longValue","123456");
 objectBox.setField("floatValue","123.456");
 objectBox.setField("shortValue","123");
 objectBox.setField("stringValue","string");
}

The MethodCache itself is multi-reentrant thread safe so you can share the MethodCache around as much as you like without fear of deadlocks, race conditions and small explosions in the server room.
Field Interceptors

Create your own concrete implementation of the FieldInterceptor abstract class by implementing the method:

String interceptFieldSet(Object target, String value, ObjectBox objectBox)

The target Object is the object which is being contained in the ObjectBox, the value String is the value which is being set and the objectBox is passed in case you want to be able to use any of its good stuff.

To use FieldInterceptors, you just add them to the ObjectBox:

TestObject testObject = new TestObject();
ObjectBox objectBox = new ObjectBox(testObject);

FieldInterceptor intercept = new MyFieldInterceptor();
objectBox.addFieldInterceptor(“madeUpField”,intercept);

objectBox.setField("doubleField", "1234.5");
objectBox.setField("madeUpField", "hello intercept!");

objectBox.invokeFieldInterceptors();

Here the fieldInterceptor is set to pretend to be a new field on the testObject bean ‘madeUpField’. You can use field interceptors to handle the setting of real fields; the interceptor will be used rather than directly setting the field’s value.

That last 'invokeFieldInterceptors()' call must be made after all of the ‘setter’ activity has finished, it’s only then that the interceptors are actually executed.

You might think that this call is completely unnecessary, and in this instance you’d be right, but FieldInterceptors can be built into an execution hierarchy so that interceptors which rely on many fields on the testObject being set before they can do their good stuff are only called when everything is just so. For example:

TestObject testObject = new TestObject();
ObjectBox objectBox = new ObjectBox(testObject);

FieldInterceptor intercept1 = new MyFieldInterceptor();
intercept.setDependencies(new String[]{“important”});

FieldInterceptor intercept2 = new MyFieldInterceptor();

objectBox.addFieldInterceptor(“madeUp”,intercept1);
objectBox.addFieldInterceptor(“important”,intercept2);

objectBox.setField("doubleField", "1234.5");
objectBox.setField("madeUp", "hello intercept!"); objectBox.setField("important", "set me first");

objectBox.invokeFieldInterceptors();

Would end up calling:

testObject.setDoubleField(1234.5d)
interceptFieldSet for “important”
interceptFieldSet for “madeUp”

Because "madeUp" depends on "important" it is called after "important" irrespective of the order in which the setField calls are made.

Fun things to make and do with FieldInterceptors:

  • Fields that aren’t really on the bean, but you want to pretend they are
  • The setting of fields which depend on a number of other fields being set first
  • Isolating complex logic from both the bean and your framework
SourceForge.net Logo
SourceForge.net Logo