FAQ
Frequently Asked Questions
Contents
I have a technical question. Whom do I ask?
How does db4o behave with large amounts of data?
I would like to license db4o for a commercial product. What are the costs?
Why can't I retrieve the objects that I stored?
Why are objects of certain classes not stored?
Where is the database driver?
What's "activation" and what is it for?
Some of my objects are not updated. Why?
What is db4o really doing with my objects?
How do I use db4o in a servlet environment or with JSPs?
I have a technical question. Whom do I ask?
If possible, please post your questions to our newsgroup news://news.db4odev.com/db4o.users.
A synchronised web- and email-interface for the newsgroup can be found at http://groups.yahoo.com/group/db4o_unmoderated.
The db4o team is monitoring all the postings and usually answers questions on the
same day.
If you do not wish to talk about your technical problems in public, please
mail your questions to
support@db4o.com.
How does db4o behave with large amounts of data?
We recommend a maximum size of 1 GB per database file. You may however use multiple database files
and move and copy objects freely between them. Navigation access times to objects and the performance
of access by internal IDs remains constant, no matter how large database files
are. Query performance does drop linearly with an increasing number of objects per class. Since db4o insert
performance is extremely good, it is very little effort to conduct your own
performance tests with large amounts of data.
I would like to license db4o for a commercial product. What are the costs?
db4o may be freely redistributed in non-commercial applications. As soon as you or
someone else has a financial benefit from running the db4o engine, however
indirect it may be, licensing costs become due. Since usecases, applications and
turnovers differ widely, db4o license fees are negotiated individually. We try to
provide equally fair offers to Fortune 100 companies and to shareware
developers. Please contact sales@db4o.com
for an individual offer.
Why can't I retrieve the objects that I stored?
First you should check, that your objects have actually been stored, by using
com.db4o.tools.Statistics. If the objects are not there, it's another FAQ.
If the objects are there:
Query-By-Example evaluates all non-null fields and all simple type variables
that do not hold their default values against the stored objects. Check to make
sure that you are not constraining the resultset by accidentally initialising
variables on your template objects. Typical places could be:
- Constructors
- Constructors in ancestors of your class
- Static initialisation
- Static initialisation in ancestors of your class.
Why are objects of certain classes not stored?
db4o needs a constructor that it can use. Ideally this is a zero-parameter
constructor, necessarily declared public if you are working on JDK versions
prior to JDK 1.2. If db4o
does not find a zero-parameter constructor, db4o iterates through all other
constructors and internally attempts to create an instance of an object by
passing appropriate null parameters. If this is successful with any of the
present constructors, this constructor is used. Consult the sample code in
com.db4o.samples.constructors for a documentation of this behaviour.
db4o supplies a configuration feature to detect problems with constructors. To
analyse problems with your code, you may want to turn the following switch
before starting the db4o engine:
Db4o.configure().exceptionsOnNotStorable(true);
There are classes that do not have usable constructors. java.net.URL is an
example from the JDK. In this case you have the following options:
- add a zero-parameter constructor specifically for db4o
- derive from the class and add a zero-parameter constructor
- add a custom translator. See the code in com.db4o.samples.translators for
examples how this can be done.
If you need to quickly implement a solution for one of the JDK classes and
querying members is not an issue, you may choose to use the built in
serializable translator. Here is an example, how this is done for java.net.URL:
Db4o.configure().
objectClass("java.net.URL").
translate(new com.db4o.config.TSerializable());
This code needs to be executed before every single start of the db4o engine.
Where is the database driver?
db4o is an independant object database engine on it's own. It does not need a database driver. All you need to do is add db4o.jar to your
CLASSPATH and you are all set to program against the db4o API.
What's "activation" and what is it for?
Let's explain this with an example:
Consider that you retrieve an object from the database by using a query. This
object might have 1000 members, all these 1000 objects might have 1000 members,
these could have 1000 members in turn and so on....
In the worst case, you would have a single root object that indirectly references all
other objects in the database. Creating all of these objects automatically
during retrieval from the database file could take a very
long time and you would probably experience OutOfMemory problems.
To solve this, db4o introduces a concept of "deactivated" objects:
All of the fields of a "deactivated" object are set to null.
The primitive types hold their default values respectively.
In db4o terms, loading the fields with the stored values from the database is
called "activation".
db4o provides an API, to configure how activation is to behave. You can set a
global activation depth and override the behaviour individually for specific
classes:
Db4o.configure().activationDepth(int)
Db4o.configure().objectClass("yourClass").minimumActivationDepth(int)
Db4o.configure().objectClass("yourClass").maximumActivationDepth(int)
By default, Db4o is configured with a standard activation depth of 5.
The term "depth" means:
"number of member references away from the original object"
Here is an example. Consider you have a default activation depth of 3. If you
retrieve an object:
object.member1.member2.member3 will be instantiated.
"member3" will be present but deactivated.
You can use manual activation to instantiate individual objects:
ObjectContainer#activate(object, depth);
Manual deactivation may be used to save memory:
ObjectContainer#deactivate(object, depth);
By configuring db4o you have full control over how you want db4o to behave. The
two extremes:
- using an activationDepth of Integer.MAX_VALUE let's you forget about manual
activation but you might not have the best performance and memory footprint
- using an activationDepth of 0 and activating and deactivating all objects
manually keeps memory consumption extremely low on
a low-memory-device.
Some of my objects are not updated. Why?
In the default configuration a call to ObjectContainer#set() only updates
objects to depth 1.
This means that all simple types, their wrappers, String and Date are updated
but not the contained individual objects.
db4o supplies the following features to alternate the behaviour:
- configuring the global update depth.
Db4o.configure().updateDepth(int depth)
- configuring the update depth for a specific class.
Db4o.configure().objectClass("yourPackage.yourClass").updateDepth(int
depth)
- cascading classes
Db4o.configure()
.objectClass("yourPackage.yourClass").cascadeOnUpdate(true)
- cascading individual fields
Db4o.configure()
.objectClass("yourClass").objectField("yourField").cascadeOnUpdate(true)
- using a callback method:
public class Foo{
Bar bar;
public void objectOnUpdate(ObjectContainer con) {
con.set(bar);
}
}
The cascadeOnUpdate(true)
configuration methods are recommended as the best choice.
What is db4o really doing with my objects?
Finding out is very simple:
Call Db4o.configure().messageLevel(4);
before opening a database
file and everything that is happening will be logged to the console. Use
Db4o.configure().setOut();
to redirect output to a PrintStream
of your choice.
How do I use db4o in a servlet environment or with JSPs?
db4o comes with a special interface for stateless servlet sessions:
ExtDb4o.objectContainer(ServletContext, HttpSession, databaseFile);
takes care of all issues:
- creating or opening the database file on demand
- associating the open file with the ServletContext and the running Session
- closing the database file when the last session is terminated
- closing and reopening the database file when the servlet application code is
changed in a running session and db4o needs to adjust to a modified ClassLoader.
Since there may be problems with the reachability of classes from different
ClassLoaders, we recommend to place db4o.jar into the ../WEB-INF/lib/ directory
of the respective application.