11. ConstructorsSometimes you may find that db4o refuses to store instances of certain classes, or appears to store them, but delivers incomplete instances on queries. To understand the problem and the alternative solutions at hand, we'll have to take a look at the way db4o "instantiates" objects when retrieving them from the database. 11.1. Instantiating objectsDb4o currently knows three ways of creating and populating an object from the database. The approach to be used can be configured globally and on a per-class basis. 11.1.1. Using a constructorThe most obvious way is to call an appropriate constructor. Db4o does not require a public or no-args constructor. It can use any constructor that accepts default (null/0) values for all of its arguments without throwing an exception. Db4o will test all available constructors on the class (including private ones) until it finds a suitable one. What if no such constructor exists? 11.1.2. Bypassing the constructorDb4o can also bypass the constructors declared for this class using platform-specific mechanisms. (For Java, this option is only available on JREs >= 1.4.) This mode allows reinstantiating objects whose class doesn't provide a suitable constructor, However, it will (silently) break classes that rely on the constructor to be executed, for example in order to populate transient members. If this option is available in the current runtime environment, it will be the default setting. 11.1.3. Using a translatorIf none of the two approaches above is suitable, db4o provides a way to specify in detail how instances of a class should be stored and reinstantiated by implementing the Translator interface and registering this implementation for the offending class. We'll cover translators in detail in the next chapter . 11.2. ConfigurationThe instantiation mode can be configured globally or on a per class basis.
This will configure db4o to use constructors to reinstantiate any object from the database. (The default isfalse).
This will configure db4o to use constructor calls for this class and all its subclasses. 11.3. TroubleshootingAt least for development code, it is always a good idea to instruct db4o to check for available constructors at storage time. (If you've configured db4o to use constructors at all.)
If this setting triggers exceptions in your code, or if instances of a class seem to lose members during storage, check the involved classes (especially their constructors) for problems similar to the ones shown in the following section. 11.4. Examples
The above class is fine for use with and without callConstructors set.
The above C2 class needs to have callConstructors set to true. Otherwise, since transient members are not stored and the constructor code is not executed, toString() will potentially run into a NullPointerException on x.length().
The above C3 class needs to have callConstructors set to false (the default), since the (only) constructor will throw a NullPointerException when called with a null value.
This class cannot be cleanly reinstantiated by db4o: Both approaches will fail, so one has to resort to configuring a translator. -- generated by Doctor courtesy of db4objects Inc. |