diff --git a/components/net/sf/briar/db/H2Database.java b/components/net/sf/briar/db/H2Database.java
index b61172b65b2ba9133f19a0b71237949fd4cc650c..18aff631c6e31920983fce34d1f7f7973d3eae07 100644
--- a/components/net/sf/briar/db/H2Database.java
+++ b/components/net/sf/briar/db/H2Database.java
@@ -38,7 +38,8 @@ class H2Database extends JdbcDatabase {
 			@DatabaseMaxSize long maxSize,
 			ConnectionWindowFactory connectionWindowFactory,
 			GroupFactory groupFactory) {
-		super(connectionWindowFactory, groupFactory, "BINARY(32)", "BINARY");
+		super(connectionWindowFactory, groupFactory, "BINARY(32)", "BINARY",
+				"INT NOT NULL AUTO_INCREMENT");
 		home = new File(dir, "db");
 		this.password = password;
 		url = "jdbc:h2:split:" + home.getPath()
diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java
index 6bd7cb3e8e4efac94876652f46ee4dcc4d63ee47..df59f88b233da6fffe215b0c15293aa1b4408d49 100644
--- a/components/net/sf/briar/db/JdbcDatabase.java
+++ b/components/net/sf/briar/db/JdbcDatabase.java
@@ -55,7 +55,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 
 	private static final String CREATE_CONTACTS =
 		"CREATE TABLE contacts"
-		+ " (contactId INT NOT NULL,"
+		+ " (contactId COUNTER,"
 		+ " secret BINARY NOT NULL,"
 		+ " PRIMARY KEY (contactId))";
 
@@ -228,7 +228,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		Logger.getLogger(JdbcDatabase.class.getName());
 
 	// Different database libraries use different names for certain types
-	private final String hashType, binaryType;
+	private final String hashType, binaryType, counterType;
 	private final ConnectionWindowFactory connectionWindowFactory;
 	private final GroupFactory groupFactory;
 	private final LinkedList<Connection> connections =
@@ -240,11 +240,13 @@ abstract class JdbcDatabase implements Database<Connection> {
 	protected abstract Connection createConnection() throws SQLException;
 
 	JdbcDatabase(ConnectionWindowFactory connectionWindowFactory,
-			GroupFactory groupFactory, String hashType, String binaryType) {
+			GroupFactory groupFactory, String hashType, String binaryType,
+			String counterType) {
 		this.connectionWindowFactory = connectionWindowFactory;
 		this.groupFactory = groupFactory;
 		this.hashType = hashType;
 		this.binaryType = binaryType;
+		this.counterType = counterType;
 	}
 
 	protected void open(boolean resume, File dir, String driverClass)
@@ -321,6 +323,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 	private String insertTypeNames(String s) {
 		s = s.replaceAll("HASH", hashType);
 		s = s.replaceAll("BINARY", binaryType);
+		s = s.replaceAll("COUNTER", counterType);
 		return s;
 	}
 
@@ -467,25 +470,24 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			// Get the highest existing contact ID
-			String sql = "SELECT contactId FROM contacts"
+			// Create a new contact row
+			String sql = "INSERT INTO contacts (secret) VALUES (?)";
+			ps = txn.prepareStatement(sql);
+			ps.setBytes(1, secret);
+			int affected = ps.executeUpdate();
+			if(affected != 1) throw new DbStateException();
+			ps.close();
+			// Get the new (highest) contact ID
+			sql = "SELECT contactId FROM contacts"
 				+ " ORDER BY contactId DESC LIMIT ?";
 			ps = txn.prepareStatement(sql);
 			ps.setInt(1, 1);
 			rs = ps.executeQuery();
-			int nextId = rs.next() ? rs.getInt(1) + 1 : 1;
-			ContactId c = new ContactId(nextId);
+			if(!rs.next()) throw new DbStateException();
+			ContactId c = new ContactId(rs.getInt(1));
 			if(rs.next()) throw new DbStateException();
 			rs.close();
 			ps.close();
-			// Create a new contact row
-			sql = "INSERT INTO contacts (contactId, secret) VALUES (?, ?)";
-			ps = txn.prepareStatement(sql);
-			ps.setInt(1, c.getInt());
-			ps.setBytes(2, secret);
-			int affected = ps.executeUpdate();
-			if(affected != 1) throw new DbStateException();
-			ps.close();
 			// Store the contact's transport properties
 			sql = "INSERT INTO contactTransports"
 				+ " (contactId, transportId, key, value)"
diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java
index 6f609e62ee98af066f706926d327bb4a08a6f9b2..fbbbbd3c6002c7c9e9599f9cf27510830a698b1f 100644
--- a/test/net/sf/briar/db/H2DatabaseTest.java
+++ b/test/net/sf/briar/db/H2DatabaseTest.java
@@ -186,9 +186,9 @@ public class H2DatabaseTest extends TestCase {
 		assertFalse(db.containsContact(txn, contactId2));
 		assertEquals(contactId2, db.addContact(txn, transports, secret));
 		assertTrue(db.containsContact(txn, contactId2));
-		// Delete one of the contacts
-		db.removeContact(txn, contactId1);
-		assertFalse(db.containsContact(txn, contactId1));
+		// Delete the contact with the highest ID
+		db.removeContact(txn, contactId2);
+		assertFalse(db.containsContact(txn, contactId2));
 		// Add another contact - a new ID should be created
 		assertFalse(db.containsContact(txn, contactId3));
 		assertEquals(contactId3, db.addContact(txn, transports, secret));