Db4o does not deliver a field autoincrement feature, which is common in RDBMS. If your application logic requires this feature you can implement it using External Callbacks. One of the possible solutions is presented below.
We will need an object to store the last generated ID and to return a new ID on request:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
/* 03
* Singleton class used to keep auotincrement information 04
* and give the next available ID on request 05
*/ 06
package com.db4odoc.callbacks; 07
08
import com.db4o.ObjectContainer; 09
import com.db4o.ObjectSet; 10
11
public class IncrementedId { 12
private int no; 13
private static IncrementedId ref; 14
15
private IncrementedId() { 16
this.no = 0; 17
} 18
19
// end IncrementedId 20
21
public int getNextID(ObjectContainer db) { 22
no++; 23
db.set(this); 24
return no; 25
} 26
27
// end increment 28
29
public static IncrementedId getIdObject(ObjectContainer db) { 30
// if ref is not assigned yet: 31
if (ref == null) { 32
// check if there is a stored instance from the previous 33
// session in the database 34
ObjectSet os = db.get(IncrementedId.class); 35
if (os.size() > 0) 36
ref = (IncrementedId) os.next(); 37
} 38
39
if (ref == null) { 40
// create new instance and store it 41
System.out.println("Id object is created"); 42
ref = new IncrementedId(); 43
db.set(ref); 44
} 45
return ref; 46
} 47
// end getIdObject 48
}
This object generates the simplest ID, which is an autoincremented integer value. You can add your own algorithm to generate more sophisticated ID sequences, like ABC0001DEF.
When you use external callbacks you are not limited to a single object: a callback can apply to any group of objects Thus you can create a sequence of classes sharing the same autoincrement. To distinguish the objects, which will have an autoincremented field, we will use an abstract (MustInherit in VB) class:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
/* 03
* This class is used to mark classes that need to get an autoincremented ID 04
*/ 05
package com.db4odoc.callbacks; 06
07
08
public abstract class CountedObject { 09
int id; 10
11
public void setId(int id){ 12
this.id = id; 13
} 14
15
public int getId(){ 16
return id; 17
} 18
}
Each object extending CountedObject will get an autoincremented ID. For example:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
package com.db4odoc.callbacks; 03
04
public class TestObject extends CountedObject{ 05
String name; 06
07
public TestObject(String name) { 08
this.name = name; 09
} 10
11
public String toString() { 12
return name+"/"+id; 13
} 14
15
}
It is only left to register the callback with the creating() event:
01public static void registerCallback(final ObjectContainer db){ 02
EventRegistry registry = EventRegistryFactory.forObjectContainer(db); 03
// register an event handler, which will assign autoincremented IDs to any 04
// object extending CountedObject, when the object is created 05
registry.creating().addListener(new EventListener4() { 06
public void onEvent(Event4 e, EventArgs args) { 07
ObjectEventArgs queryArgs = ((ObjectEventArgs) args); 08
Object obj = queryArgs.object(); 09
// only for the objects extending the CountedObject 10
if (obj instanceof CountedObject){ 11
((CountedObject)obj).setId(getNextId(db)); 12
} 13
} 14
}); 15
}
1private static int getNextId(ObjectContainer db) { 2
// this function retrieves the next available ID from 3
// the IncrementedId object 4
IncrementedId r = IncrementedId.getIdObject(db); 5
int nRoll; 6
nRoll = r.getNextID(db); 7
8
return nRoll; 9
}
You can test the results with the following code:
1public static void storeObjects(ObjectContainer db){ 2
TestObject test; 3
test = new TestObject("FirstObject"); 4
db.set(test); 5
test = new TestObject("SecondObject"); 6
db.set(test); 7
test = new TestObject("ThirdObject"); 8
db.set(test); 9
}
1public static void retrieveObjects(ObjectContainer db){ 2
ObjectSet result = db.get(new TestObject(null)); 3
listResult(result); 4
}