Db4o ( database for objects ) is an object database for Java and. NET platform and is one of the NoSQL databases. The db4o program library is characterized by a comparatively small memory footprint of about 600 kB. This makes them ideal for embedding into other programs and for environments with limited memory resources, such as PDAs. Db4o is available both in free as well as commercial licenses.

Db4o supports Java JDK 1.1.x to 6.0 and runs natively on J2EE, J2SE and J2ME all configurations whose J2ME profile provides the Reflection API. In addition db4o supports all languages ​​that are based on the virtual machine, the CLR. NET platform, such as C # or VB.NET. The necessary for. NET platform, C # source code of the program db4o library is thereby generated mostly from the Java source code, and is, for example, run on the Mono implementation of. NET platform.

  • 8.1 Internal callbacks
  • 8.2 External Callbacks

System Properties and Property Management

  • Next to the small memory requirements for the program library of the memory requirements at runtime also small and usually does not exceed 1 MB.
  • Db4o can not be administered from the outside. All settings must be made on the program code.
  • The database can be used in mixed environments: For example, two programmed in C # or Java client applications share access to a database that is operated by a programmed in Java or C # server application. Using the alias features of db4o class -name can be renamed, which is necessary, for example, because of the different naming conventions.
  • One of the main advantages of db4o: Objects can be stored without the need for special precautions must be taken. It is not necessary to derive the classes to be stored special superclasses, still need special interfaces are implemented. Also, an enrichment of the bytecodes, such as those used, for example, the aspect -oriented programming is not necessary. The objects can be contained any type and also nested arbitrarily deep.
  • With this feature it is possible to implement persistence with little effort.

Basic API

API ( application programming interface ) indicates the programming interface with which the database is programmed. It turns out that the difference to other programs such as Hibernate or JPA / EJB is not too large.

A simple code example that should be continuously performed:

/ / Open a database    Object Container db = Db4o.openFile ("C :/ beispiel.db ");    try {       / / Store two people       db.store ( new Person ( " John Doe ", " TOP INC. ", 45) );       db.store ( new Person ( " Clara sky ", " BB Radio", 30) );       / / Iterate over all persons       ObjectSet result = db.queryByExample ( new Person ());       while ( result.hasNext ()) {           System.out.println ( result.next ());       }       / / Changes Dere a person       result = db.queryByExample ( new Person ( " Clara sky "));       Person found = (Person) result.next ();       found.setAge (25);       db.store ( found);       / / Delete a person       db.delete ( found);       / / Write out the changes       db.commit ();    }    finally {       / / Close the database       db.close ();    } Similar to EJB / JPA ( EntityManager there ) an object container is created as an object manager first. This container can either refer to a file or. , In a client -server architecture on a hosted from a server database In the first case all the data is stored in a file. Disadvantage: The data is not completely independent of the class of programming language. The format is proprietary and may optionally be read not as easy of following programming languages. Advantage: It can be very easily exchanged between companies. The data access is very fast.

After all CRUD ( Create, Read, Update and Delete) are performed:

Query languages

Db4o offers three query languages ​​, all of which are not all too far away from what have Hibernate and JPA in EJB 3.0:

Query By Example ( QBE )

Query by Example for a search using examples. The foundations were already laid in the 70 years of Moshé M. Zloof in some articles. Hibernate and db4o provide this mechanism in a slightly weaker version.

With db4o can as shown above any object to be created. Then either:

  • No field is set, so that all fields are null, or it is directly passed a reference to the class (eg Person.class ): In this case, all are returned stored in the database instances of the class.
  • There are arbitrarily set many fields: Then all stored objects are returned for which match the pattern fields filled in with the value in the object.
  • There null is passed: This returns all objects from the database.

Complex query criteria can not be expressed using this type of query.

SODA / Criteria Queries

Internally, all queries are mapped to at db4o SODA. SODA is the programming of the SODA project hosted on SourceForge - Simple Object Database Access, which is partially supervised but independent of db4o db4o developed by the developers.

The SODA queries very similar to those of Hibernate Criteria queries. An example:

Query query = db.query ();   query.constrain ( Person.class );   query.descend ( "old" ) constrain ( 50) Greater ().. ;   ObjectSet result = query.execute (); Here the query is initially limited to the Person class. Go ahead on all persons who are older than 50.

It is in this type of query is an example of Query by API, are created when trees of objects with which queries are limited. It is therefore more powerful than the other query mechanisms, but also harder to create because the code is harder to read. By using string as a query parameter type safety is not guaranteed for compilation time.

Native queries

Native queries (English native queries ) are queries that are formulated in the language of the client application. So for example db4o in Java or C #.

The code native query is not normally carried out at db4o, but analyzed at runtime. Based on the result of the analysis, a SODA Criteria Query is created. This has the advantage that the persisted objects must not be instantiated time consuming. Only if the analysis fails due to the complexity of the query, the object instance is created and the program code of the native query needs to be executed.

For comparison, native query and JPQL or HQL, please refer to Microsoft's LINQ here. Microsoft could change the language and embed so powerful query constructs directly in C #.


  • The programmer has no special query language, such as SQL, learn.
  • The queries use the elements of the programming language and therefore are type-safe.
  • In the transformation ( refactoring ) of the program, the queries can be considered.

Faulty Queries are identified earlier, for these reasons, or more commonly causes rather avoided by avoiding, as this is the case when specific query languages ​​.


  • The creation of the query is completely in the hands of the developer and not under the control of administrators who may consider appropriate, for example when using Stored Procedures safety aspects of the database.
  • Native queries are not as powerful as the corresponding constructs in specialized query languages ​​such as HQL or JPQL. In these languages, may require special query criteria, such as compaction, can be expressed explicitly.


It is crucial for comfortable use, whether and how the language used Closures supported. Without Closure support necessary to work with inner classes or unbound methods pointers or delegates to pass the query as " free-floating code" of a method.

C # NET 3.0 ( using a lambda expression ). ;

Var persons = db.Query (s = > s.Age > 50);. C # NET 2.0 ( using an unbound method pointer ):

IList persons = db.Query ( delegate ( Person person) {     return person.age > 50;   }); Java JDK 5 ( using a generic anonymous class ):

List people = db.query (new Predicate () {     public boolean match ( Person person) {       return person.getAge () > 50;     }   }); Java JDK 1.2 to 1.4 ( using an anonymous class ):

List people = db.query (new Predicate () {     public boolean match ( Object object) {       Person person = (Person) object;       return person.getAge () > 50;     }   }); Java JDK 1.1 ( using an inner class):

ObjectSet people = db.query ( new Person filters ());     public static class Person { filter extends Predicate     public boolean match ( Object object) {       Person person = (Person) object;       return person.getAge () > 50;     }   } transactions

With the opening of the container from the above example, a transaction is created. This can be written at any time, or rejected with db.commit () or db.rollback () to the database. Db4o guarantees an ACID behavior. Everything within a transaction meets the ACID requirements. Internally, all accesses are serialized to the database within the transaction. This has strong implications for the database system:

  • Due to the proprietary data format of the access for a thread online is usually faster than other combinations of relational database and objektrelationalem mapping.
  • Nevertheless scales a " multithreaded " access at db4o not yet, as it is necessary, for example for the construction of large web portals.

According to experiences normally up to a dozen hits per second are possible, which may be sufficient for many applications. However, db4o works because of the above points to a server version that scales well with concurrent accesses.

Client / server mode

Db4o offers several operating modes:

Example of the server:

Object Server server = Db4oClientServer.openServer ("c :/ liveserver.db ", 8732 ); server.grantAccess ( "user1", "password "); server.grantAccess ( "user2 ", "password "); Here's a thread is opened, waiting for client requests on port 8732. The server itself can wait on monitors and for example make state spending. Access rights can not be managed directly from the outside by means of a tool. Either these are created in the code or read via console etc..

A client could be initially set up as follows:

AClient = Db4oClientServer.openClient ( " ", 8732, "user2 ", "password ");

By means of a so-called " out-of- band signaling " communication protocol can the server any objects are sent, with which a server can be administered. For example, the request may be forwarded to defragment the file.


Means fewer lines Any number of replicated servers ( clustered ) are. This is done with the db4o dRS module.

The objects to get a unique UUID. This allows individual objects or the entire database to be distributed uni- or bidirectional. That each new object is sent to all other databases. This allows to set up large and redundant architectures.

Very interesting is also the option to replicate a db4o database in relational databases. This is a bridge / connection to both worlds, which are often considered separately. db4o used Hibernate. After configuring the bridge dRS individual objects or entire databases can also be optionally transferred via trigger in one or both directions. In many cases, so the advantages of both worlds can be well utilized in the industry.

Charging behavior

With db4o, there are three modes for loading objects:

Objects usually form deep reference structures. In db4o can be specified when loading objects, the depth to which referenced objects should be loaded implicitly with the object. It is also possible to explicitly activate these referenced objects at a later time. For more information on activation, deactivation, querying, and updating of referenced objects can be found in the db4o reference.


With db4o, there are internal and external callback functions ( callbacks ). These are similar in meaning to the database triggers other databases. Callback mechanisms exist in many products for database connection and are a powerful tool for example, checks to perform to set default values ​​or to take into account safety aspects.

Internal callbacks

Internal callbacks are added to the classes of objects to be stored as methods. These are dynamically discovered and called by db4o using the reflection. For this purpose, it is not necessary to derive the class of special interfaces. Similar to the join point aspect-oriented programming are ago Views internal callbacks and after database-related events possible. The call time is in this case determined by the prefix of the method name: objectCan ... methods before and objectOn ... methods are called after the event. By the return value of objectCan ... methods can be used to control whether the action associated with the event is to take place. For the internal callbacks, the following events are available: New, Update, Delete, Activate and Deactivate.

External Callbacks

External callbacks are not assigned to classes. Instead, they are registered with the object container. In addition to the potential at the internal callbacks events available for these callbacks Query Started and QueryFinished available. The use of external callback allows an event handler without modifying the classes to be stored. This may have the advantage that aspects of the persistence need not be mixed with the business logic. If the source code of the classes to be stored is not available, must be used with external callbacks.


Db4o is licensed since 2004 either under the GPL as free software or under a commercial license that allows use in non - GPL projects. Besides there is a classpath -like license that allows to integrate db4o in open source projects that are not db4o / GPL compliant.


The db4o project began in 2000 under the leadership of Carl Rosenberger. Db4o is developed by the company db4objects, Inc., which was founded with the support of investors including Mark Leslie (VERITAS Software ), Vinod Khosla (Sun Microsystems) and Jerry Fiddler ( Wind River) in 2004.

In December 2008, the database division was sold to Versant. In the course of this business db4objects works in the future under the name of Servo Software, Inc. in the topic "user data management " probably for services in the wireless market.