diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
index 60d69108635ab4312b26d8e2b425ef554f1f80c2..2d8ea030453eb2c1591e6c74a10c9c4a48747c2d 100644
--- a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
+++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
@@ -72,9 +72,8 @@ public class ADConnector implements AuthenticationSource {
         endpoint.setUserAccountName(
                 ADConnector.settings.getRealm()
                         + "\\"
-                        + settings
-                                .getUsername()); // * You can use the user's Distinguished Name as
-                                                 // well
+                        + settings.getUsername()); // * You can use the user's Distinguished Name as
+        // well
         endpoint.setPassword(settings.getPassword());
         return endpoint;
     }
diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java
index 1e1bf0d78d5f93e75d43daddcd9c8279faca79b7..95c6bb00f6f1c84921a7abf885ff4d8901cdec2b 100644
--- a/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java
+++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java
@@ -43,8 +43,6 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
 import net.jami.jams.ad.connector.ADConnector;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.UserProfile;
 
 import java.util.*;
@@ -138,12 +136,7 @@ public class UserProfileService {
                             .map(UserProfileService::profileFromResponse)
                             .collect(Collectors.toList());
             for (UserProfile p : profilesFromResponse) {
-                StatementList statementList = new StatementList();
-                StatementElement st = new StatementElement("username", "=", p.getUsername(), "");
-                statementList.addStatement(st);
-
-                if (dataStore.getUserProfileDao().getObjects(statementList).isEmpty())
-                    dataStore.getUserProfileDao().storeObject(p);
+                dataStore.getUserProfileDao().insertIfNotExists(p);
             }
 
             return profilesFromResponse;
diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java b/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java
index 27ee8f4184abb190413ef883a697ce132376e27a..30eef877f425d2af48516cf8bd50bc6f66e32982 100644
--- a/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java
+++ b/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java
@@ -72,7 +72,6 @@ public class TokenController {
         SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims);
         try {
             signedJWT.sign(new RSASSASigner(signingKey));
-            UserAuthenticationModule.datastore.getJwtDao().storeObject(signedJWT);
             authTokenResponse.setAccess_token(signedJWT.serialize());
             authTokenResponse.setExpires_in(30 * 60L);
             authTokenResponse.setToken_type("Bearer");
diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
index 89a515a4b0472341a996e672f3c34526708c6603..0f3dc031398f879d360663a815089cfe4da42338 100644
--- a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
+++ b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
@@ -33,8 +33,6 @@ import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.common.authmodule.AuthTokenResponse;
 import net.jami.jams.common.authmodule.AuthenticationModule;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.jami.NameServer;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
@@ -55,6 +53,7 @@ import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.security.interfaces.RSAPublicKey;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
 @Slf4j
@@ -159,11 +158,8 @@ public class UserAuthenticationModule implements AuthenticationModule {
     public AuthTokenResponse authenticateUser(String username, String password) {
         AuthTokenResponse res = null;
         String hashPass = "";
-        if (datastore.userExists(username)) {
-            StatementList statementList = new StatementList();
-            StatementElement statementElement = new StatementElement("username", "=", username, "");
-            statementList.addStatement(statementElement);
-            User user = datastore.getUserDao().getObjects(statementList).get(0);
+        if (datastore.getUserDao().getByUsername(username).isPresent()) {
+            User user = datastore.getUserDao().getByUsername(username).orElseThrow();
             if ((user.getUserType() == AuthenticationSourceType.LOCAL))
                 hashPass = PasswordUtil.hashPassword(password, Base64.decodeBase64(user.getSalt()));
             else hashPass = password;
@@ -174,12 +170,11 @@ public class UserAuthenticationModule implements AuthenticationModule {
                             .authenticate(username, hashPass))
                 return tokenController.getToken(user, null);
         }
-        // The second case is much more violent, because we don't know in advance "where" this user
-        // comes
-        // from, so we have to infer (this is only really true for "users", all others are usually
-        // pre-marked)
-        // This is also the case when we store the user into the DAO - because he never existed
-        // before.
+        // The second case is much more violent, because we don't know in
+        // advance "where" this user comes from, so we have to infer
+        // (this is only really true for "users", all others are usually pre-marked)
+        // This is also the case when we store the user into the DAO
+        // - because he never existed before.
         for (AuthModuleKey key : authenticationSources.keySet()) {
             if (authenticationSources.get(key).authenticate(username, password)) {
                 User user = new User();
@@ -211,10 +206,7 @@ public class UserAuthenticationModule implements AuthenticationModule {
             if (crl.getRevokedCertificate(clientCert.getSerialNumber()) != null) return null;
             String username = X509Utils.extractDNFromCertificate(clientCert).get("CN");
             // We need to extract the deviceId from the certificate
-            StatementList statementList = new StatementList();
-            StatementElement statementElement = new StatementElement("username", "=", username, "");
-            statementList.addStatement(statementElement);
-            User user = datastore.getUserDao().getObjects(statementList).get(0);
+            User user = datastore.getUserDao().getByUsername(username).orElseThrow();
             return tokenController.getToken(
                     user, X509Utils.extractDNFromCertificate(deviceCert).get("UID"));
         } catch (Exception e) {
@@ -261,14 +253,8 @@ public class UserAuthenticationModule implements AuthenticationModule {
 
     @Override
     public char[] getOTP(String username) {
-        if (datastore.userExists(username)) {
-            StatementList statementList = new StatementList();
-            StatementElement statementElement = new StatementElement("username", "=", username, "");
-            statementList.addStatement(statementElement);
-            User user = datastore.getUserDao().getObjects(statementList).get(0);
-            return (user.getPassword()).toCharArray();
-        }
-        return new char[0];
+        Optional<User> user = datastore.getUserDao().getByUsername(username);
+        return user.map(u -> u.getPassword().toCharArray()).orElse(new char[0]);
     }
 
     @Override
diff --git a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java
index 0e7f88265b66f1e135465cb5dad5cfe34a797e8d..bd3cee618fc168761cbe83b08f4746d66418ca6a 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java
@@ -27,89 +27,113 @@ import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.DeleteStatementBuilder;
-import net.jami.jams.common.dao.SelectStatementBuilder;
-import net.jami.jams.common.dao.StatementConstraints;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.UpdateStatementBuilder;
 import net.jami.jams.common.dao.connectivity.SQLConnection;
+import net.jami.jams.common.serialization.database.DatabaseObject;
 
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public abstract class AbstractDao<T> {
 
     @Getter @Setter private String tableName;
-    @Getter @Setter private Class<T> tClass;
+    @Getter @Setter protected Class<T> tClass;
 
     public abstract boolean storeObject(T object);
 
-    public List<T> getObjects(StatementList constraints) {
-        List<T> result = new ArrayList<>();
+    protected ResultSet executeQuery(String query) {
+        return executeQuery(query, new ArrayList<>());
+    }
+
+    protected ResultSet executeQuery(String query, String param) {
+        return executeQuery(query, List.of(param));
+    }
+
+    protected ResultSet executeQuery(String query, List<String> params) {
         SQLConnection connection = DataStore.connectionPool.getConnection();
         try {
-            PreparedStatement ps =
-                    SelectStatementBuilder.buildStatement(tableName, constraints, null, connection);
-            ResultSet rs = ps.executeQuery();
-            while (rs.next()) {
-                result.add(tClass.getConstructor(ResultSet.class).newInstance(rs));
+            PreparedStatement ps = connection.getConnection().prepareStatement(query);
+            for (int i = 0; i < params.size(); i++) {
+                ps.setString(i + 1, params.get(i));
             }
-            return result;
+            return ps.executeQuery();
         } catch (Exception e) {
-            log.error("An error has occurred while trying to fetch an object: " + e);
+            log.error("An error has occurred while trying to fetch an object:");
+            e.printStackTrace();
             return null;
         } finally {
             DataStore.connectionPool.returnConnection(connection);
         }
     }
 
-    public List<T> getObjects(
-            StatementList constraints, StatementConstraints statementConstraints) {
+    protected Optional<T> getFirstObjectFromResultSet(ResultSet rs) {
+        try {
+            if (rs.next()) {
+                T obj = tClass.getConstructor(ResultSet.class).newInstance(rs);
+                rs.close();
+                return Optional.of(obj);
+            }
+        } catch (Exception e) {
+            log.error(
+                    "An error has occurred while trying to get the first result from the database:");
+            e.printStackTrace();
+        }
+
+        return Optional.empty();
+    }
+
+    protected List<T> getObjectsFromResultSet(ResultSet rs) {
         List<T> result = new ArrayList<>();
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+
         try {
-            PreparedStatement ps =
-                    SelectStatementBuilder.buildStatement(
-                            tableName, constraints, statementConstraints, connection);
-            ResultSet rs = ps.executeQuery();
             while (rs.next()) {
                 result.add(tClass.getConstructor(ResultSet.class).newInstance(rs));
             }
-            return result;
+
+            rs.close();
         } catch (Exception e) {
-            log.error("An error has occurred while trying to fetch a device: " + e);
-            return null;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
+            log.error("An error has occurred while trying to get results from the database:");
+            e.printStackTrace();
         }
+
+        return result;
     }
 
-    public boolean updateObject(StatementList update, StatementList constraints) {
+    protected boolean executeUpdate(String query, List<String> params) {
         SQLConnection connection = DataStore.connectionPool.getConnection();
+
         try {
-            PreparedStatement ps =
-                    UpdateStatementBuilder.buildStatement(
-                            tableName, update, constraints, connection);
-            return ps.execute();
+            PreparedStatement ps = connection.getConnection().prepareStatement(query);
+
+            for (int i = 0; i < params.size(); i++) {
+                ps.setString(i + 1, params.get(i));
+            }
+
+            return ps.executeUpdate() != 0;
         } catch (Exception e) {
-            log.error("An error has occurred while trying to fetch a device: " + e);
+            log.error("An error has occurred while trying to execute update:");
+            e.printStackTrace();
             return false;
         } finally {
             DataStore.connectionPool.returnConnection(connection);
         }
     }
 
-    public boolean deleteObject(StatementList delete) {
+    protected boolean executeInsert(String query, DatabaseObject object) {
         SQLConnection connection = DataStore.connectionPool.getConnection();
+
         try {
-            PreparedStatement ps =
-                    DeleteStatementBuilder.buildStatement(tableName, delete, connection);
+            PreparedStatement ps = connection.getConnection().prepareStatement(query);
+
+            ps = object.getInsert(ps);
+
             return ps.executeUpdate() != 0;
         } catch (Exception e) {
-            log.error("An error has occurred while trying to fetch a device: " + e);
+            log.error("An error has occurred while trying to execute insert:");
+            e.printStackTrace();
             return false;
         } finally {
             DataStore.connectionPool.returnConnection(connection);
diff --git a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java
index 63e839c46be4ea2f491283120afae9edafdf5985..c42385e1c9e4335451b6ff5121b05cc47318fd07 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java
@@ -26,12 +26,11 @@ package net.jami.datastore.dao;
 import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.contacts.Contact;
 
 import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.sql.ResultSet;
 import java.util.List;
 
 @Slf4j
@@ -42,24 +41,18 @@ public class ContactDao extends AbstractDao<Contact> {
         this.setTClass(Contact.class);
     }
 
+    public List<Contact> getByOwner(String owner) {
+        ResultSet rs = executeQuery("SELECT * FROM contacts WHERE owner = ?", owner);
+        return getObjectsFromResultSet(rs);
+    }
+
     // Not used because the strategy here is different.
     @Override
     public boolean storeObject(Contact object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            String insert =
-                    "INSERT INTO contacts (owner, uri, displayName, `timestamp`, status) VALUES "
-                            + "(?, ?, ?, ?, ?)";
-            PreparedStatement ps = connection.getConnection().prepareStatement(insert);
-            object.getInsert(ps);
-            ps.executeQuery();
-            return true;
-        } catch (Exception e) {
-            log.error("Could not update contacts!");
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+        String query =
+                "INSERT INTO contacts (owner, uri, displayName, timestamp, status)"
+                        + " VALUES (?, ?, ?, ?, ?)";
+        return executeInsert(query, object);
     }
 
     public boolean storeContactList(List<Contact> contactList) {
@@ -86,23 +79,8 @@ public class ContactDao extends AbstractDao<Contact> {
         }
     }
 
-    @Override
-    public boolean deleteObject(StatementList constraints) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement("DELETE FROM contacts WHERE owner = ? AND uri = ?");
-            ps.setString(1, constraints.getStatements().get(0).getValue());
-            ps.setString(2, constraints.getStatements().get(1).getValue());
-            return ps.executeUpdate() != 0;
-        } catch (SQLException e) {
-            log.error("Could not delete contact: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean deleteObject(String owner, String uri) {
+        String query = "DELETE FROM contacts WHERE owner = ? AND uri = ?";
+        return executeUpdate(query, List.of(owner, uri));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java
index fb1310820a206016a9dad4087542247262f50c01..79b085ded151d9f5cdd18d026d52d1d8047a7993 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java
@@ -25,12 +25,11 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.devices.Device;
 
-import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class DeviceDao extends AbstractDao<Device> {
@@ -40,51 +39,30 @@ public class DeviceDao extends AbstractDao<Device> {
         this.setTClass(Device.class);
     }
 
-    @Override
-    public boolean storeObject(Device object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO devices "
-                                            + "(deviceId, owner, displayName, certificate, privatekey) "
-                                            + "VALUES "
-                                            + "(?, ?, ?, ?, ?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a user: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<Device> getByOwner(String owner) {
+        ResultSet rs = executeQuery("SELECT * FROM devices WHERE owner = ?", List.of(owner));
+        return getObjectsFromResultSet(rs);
     }
 
-    @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
-        String deviceName = update.getStatements().get(0).getValue();
-        String user = update.getStatements().get(1).getValue();
-        String deviceId = update.getStatements().get(2).getValue();
+    public Optional<Device> getByDeviceIdAndOwner(String deviceId, String owner) {
+        // TODO deviceId is the primary key, owner is possibly a useless field
+        String query = "SELECT * FROM devices WHERE deviceId = ? AND owner = ?";
+        ResultSet rs = executeQuery(query, List.of(deviceId, owner));
+        return getFirstObjectFromResultSet(rs);
+    }
 
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    @Override
+    public boolean storeObject(Device object) {
+        String query =
+                "INSERT INTO devices "
+                        + "(deviceId, owner, displayName, certificate, privatekey) "
+                        + "VALUES "
+                        + "(?, ?, ?, ?, ?)";
+        return executeInsert(query, object);
+    }
 
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE devices SET displayName = ? WHERE owner = ? AND deviceId = ?");
-            ps.setString(1, deviceName);
-            ps.setString(2, user);
-            ps.setString(3, deviceId);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a user: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean updateObject(String deviceName, String username, String deviceId) {
+        String query = "UPDATE devices SET displayName = ? WHERE owner = ? AND deviceId = ?";
+        return executeUpdate(query, List.of(deviceName, username, deviceId));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
index 301b00973ac2cb45ce0e2cee3fc8668d8d9daec6..1c1c2b0622c17a13ad6f1f5a9a1d36c22458ce13 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
@@ -2,13 +2,11 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.Group;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class GroupDao extends AbstractDao<Group> {
@@ -18,69 +16,29 @@ public class GroupDao extends AbstractDao<Group> {
         this.setTClass(Group.class);
     }
 
-    @Override
-    public boolean storeObject(Group object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO groups "
-                                            + "(id, name, blueprint) VALUES (?, ?, ?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (SQLException e) {
-            log.error("An error has occurred while trying to store a group: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<Group> getAll() {
+        ResultSet rs = executeQuery("SELECT * FROM groups");
+        return getObjectsFromResultSet(rs);
     }
 
-    @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
-
-        String id = update.getStatements().get(0).getValue();
-        String name = update.getStatements().get(1).getValue();
-        String blueprint = update.getStatements().get(2).getValue();
-
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE groups SET name = ?, blueprint = ? WHERE id = ?");
-            ps.setString(1, name);
-            ps.setString(2, blueprint);
-            ps.setString(3, id);
-            return ps.executeUpdate() != 0;
-        } catch (SQLException e) {
-            log.error("An error has occurred while trying to update a group: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public Optional<Group> getById(String id) {
+        ResultSet rs = executeQuery("SELECT * FROM groups WHERE id = ?", List.of(id));
+        return getFirstObjectFromResultSet(rs);
     }
 
     @Override
-    public boolean deleteObject(StatementList constraints) {
+    public boolean storeObject(Group object) {
+        String query = "INSERT INTO groups " + "(id, name, blueprint) VALUES (?, ?, ?)";
+        return executeInsert(query, object);
+    }
 
-        String id = constraints.getStatements().get(0).getValue();
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    public boolean updateObject(String id, String name, String blueprint) {
+        String query = "UPDATE groups SET name = ?, blueprint = ? WHERE id = ?";
+        return executeUpdate(query, List.of(id, name, blueprint));
+    }
 
-        try {
-            PreparedStatement ps =
-                    connection.getConnection().prepareStatement("DELETE FROM groups WHERE id = ?");
-            ps.setString(1, id);
-            return ps.executeUpdate() != 0;
-        } catch (SQLException e) {
-            log.error("An error has occurred while trying to delete a group: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean deleteObject(String id) {
+        String query = "DELETE FROM groups WHERE id = ?";
+        return executeUpdate(query, List.of(id));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java b/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java
deleted file mode 100644
index b22ce1d55c1e978f401bae1e28ba21a261c77d6f..0000000000000000000000000000000000000000
--- a/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.jami.datastore.dao;
-
-import com.nimbusds.jwt.SignedJWT;
-
-import lombok.extern.slf4j.Slf4j;
-
-import net.jami.jams.common.dao.StatementList;
-
-import java.util.List;
-
-@Slf4j
-public class JwtDao extends AbstractDao<SignedJWT> {
-
-    private static final String SQL_STORE_TOKEN =
-            "INSERT INTO tokens (userid,deviceId,token) VALUES (?,?,?)";
-    private static final String SQL_DELETE_TOKEN =
-            "DELETE FROM tokens WHERE userid = ? AND deviceId = ?";
-    private static final String SQL_GET_TOKEN = "SELECT COUNT(token) FROM tokens WHERE token = ?";
-
-    public JwtDao() {
-        this.setTableName("tokens");
-        this.setTClass(SignedJWT.class);
-    }
-
-    @Override
-    public boolean storeObject(SignedJWT object) {
-        // TODO: Implement this.
-        return true;
-    }
-
-    public boolean validateToken(SignedJWT signedJWT) {
-        // TODO: Implement this.
-        return true;
-    }
-
-    // This method is not needed because we are only concerned with the existence of a token,
-    // we never actually look them up.
-    @Override
-    public List<SignedJWT> getObjects(StatementList constraints) {
-        return null;
-    }
-
-    // TODO: Implement this method.
-    @Override
-    public boolean deleteObject(StatementList delete) {
-        return false;
-    }
-}
diff --git a/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java b/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java
index f26411982b8d41af47baa7a5e7c59303299774e1..3084dcd0d2dbeec6e9b4eadc91ef96858638649d 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java
@@ -2,13 +2,11 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.Policy;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class PolicyDao extends AbstractDao<Policy> {
@@ -18,69 +16,41 @@ public class PolicyDao extends AbstractDao<Policy> {
         this.setTClass(Policy.class);
     }
 
-    @Override
-    public boolean storeObject(Policy object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO policies " + "(name, policyData) VALUES (?, ?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a blueprint: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<Policy> getAll() {
+        ResultSet rs = executeQuery("SELECT * FROM policies");
+        return getObjectsFromResultSet(rs);
     }
 
-    @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
-        String name = update.getStatements().get(0).getValue();
-        String policyData = update.getStatements().get(1).getValue();
-        String oldName = constraints.getStatements().get(0).getValue();
-
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    public Optional<Policy> getByName(String name) {
+        String q = "SELECT * FROM policies WHERE name = ?";
+        ResultSet rs = executeQuery(q, List.of(name));
+        return getFirstObjectFromResultSet(rs);
+    }
 
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE policies SET name = ?, policyData = ? WHERE name = ?");
-            ps.setString(1, name);
-            ps.setString(2, policyData);
-            ps.setString(3, oldName);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a blueprint: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public Optional<Policy> getByUsername(String username) {
+        // TODO this can return multiple policies
+        String query =
+                "SELECT * FROM usergroupmappings ugm"
+                        + " JOIN groups g ON ugm.groupid = g.id"
+                        + " JOIN policies p ON g.blueprint = p.name"
+                        + " WHERE ugm.username = ?";
+        ResultSet rs = executeQuery(query, List.of(username));
+        return getFirstObjectFromResultSet(rs);
     }
 
     @Override
-    public boolean deleteObject(StatementList constraints) {
+    public boolean storeObject(Policy object) {
+        String query = "INSERT INTO policies (name, policyData) VALUES (?, ?)";
+        return executeInsert(query, object);
+    }
 
-        String name = constraints.getStatements().get(0).getValue();
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    public boolean updateObject(String name, String policyData) {
+        String query = "UPDATE policies SET policyData = ? WHERE name = ?";
+        return executeUpdate(query, List.of(policyData, name));
+    }
 
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement("DELETE FROM policies WHERE name = ?");
-            ps.setString(1, name);
-            return ps.executeUpdate() != 0;
-        } catch (SQLException e) {
-            log.error("An error has occurred while trying to delete a blueprint: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean deleteObject(String name) {
+        String query = "DELETE FROM policies WHERE name = ?";
+        return executeUpdate(query, List.of(name));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java
index 6babcfc935048b87a476c8fbbef57059ae8ff661..53da8855e3dba6b5142072c095a183d1a96c679c 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java
@@ -25,12 +25,10 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.system.SystemAccount;
 
-import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Optional;
 
 @Slf4j
 public class SystemDao extends AbstractDao<SystemAccount> {
@@ -40,30 +38,20 @@ public class SystemDao extends AbstractDao<SystemAccount> {
         this.setTClass(SystemAccount.class);
     }
 
-    @Override
-    public boolean storeObject(SystemAccount object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO system "
-                                            + "(entity,certificate,privatekey)"
-                                            + "VALUES "
-                                            + "(?, ?, ?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a system entity: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public Optional<SystemAccount> getCA() {
+        ResultSet rs = executeQuery("SELECT * FROM system WHERE entity = 'CA'");
+        return getFirstObjectFromResultSet(rs);
+    }
+
+    public Optional<SystemAccount> getOCSP() {
+        ResultSet rs = executeQuery("SELECT * FROM system WHERE entity = 'OCSP'");
+        return getFirstObjectFromResultSet(rs);
     }
 
     @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
-        return false;
+    public boolean storeObject(SystemAccount object) {
+        String query =
+                "INSERT INTO system " + "(entity,certificate,privatekey)" + "VALUES " + "(?, ?, ?)";
+        return executeInsert(query, object);
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java
index 6be8ca590e777ec6d754b805ca4bebb14546a20d..75772d94003fda2b55fb00c2ed728b1242fb730e 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java
@@ -25,12 +25,11 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.User;
 
-import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class UserDao extends AbstractDao<User> {
@@ -40,74 +39,45 @@ public class UserDao extends AbstractDao<User> {
         this.setTClass(User.class);
     }
 
-    @Override
-    public boolean storeObject(User object) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO users "
-                                            + "(username, password, userType, realm, ethAddress, ethKey, jamiId,certificate, privatekey, accessLevel, needsPasswordReset, salt) "
-                                            + " VALUES "
-                                            + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a user: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<User> getAll() {
+        ResultSet rs = executeQuery("SELECT * FROM users");
+        return getObjectsFromResultSet(rs);
     }
 
-    public boolean updateUserCertificate(String username, String certificate) {
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE users SET certificate = ? WHERE username = ?");
-            ps.setString(1, certificate);
-            ps.setString(2, username);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a user certificate: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public Optional<User> getByUsername(String username) {
+        ResultSet rs = executeQuery("SELECT * FROM users WHERE username = ?", username);
+        return getFirstObjectFromResultSet(rs);
     }
 
-    @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
+    public List<User> getByJamiId(String jamiId) {
+        ResultSet rs = executeQuery("SELECT * FROM users WHERE jamiId = ?", jamiId);
+        return getObjectsFromResultSet(rs);
+    }
 
-        String pw = update.getStatements().get(0).getValue();
-        String salt = "";
-        if (update.getStatements().size() > 1) salt = update.getStatements().get(1).getValue();
+    @Override
+    public boolean storeObject(User object) {
+        String query =
+                "INSERT INTO users "
+                        + "(username, password, userType, realm, ethAddress, ethKey, jamiId,certificate, privatekey, accessLevel, needsPasswordReset, salt) "
+                        + " VALUES "
+                        + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
 
-        String user = constraints.getStatements().get(0).getValue();
+        return executeInsert(query, object);
+    }
 
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    public boolean updateUserCertificate(String username, String certificate) {
+        String query = "UPDATE users SET certificate = ? WHERE username = ?";
+        return executeUpdate(query, List.of(certificate, username));
+    }
 
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE users SET password = ?, salt = ? WHERE username = ?");
-            ps.setString(1, pw);
-            ps.setString(2, salt);
-            ps.setString(3, user);
+    public boolean updateObject(String password, String username) {
+        String query =
+                "UPDATE users SET password = ?, needsPasswordReset = 'true' WHERE username = ?";
+        return executeUpdate(query, List.of(password, username));
+    }
 
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a user: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean updateObject(String password, String salt, String username) {
+        String query = "UPDATE users SET password = ?, salt = ? WHERE username = ?";
+        return executeUpdate(query, List.of(password, salt, username));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
index 98afdfcbcb8eeeeaf3c7f0cff9f33396815013d9..e585421e41544df5ae94e2020a44a81b5de83850 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
@@ -2,13 +2,11 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.UserGroupMapping;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping> {
@@ -18,60 +16,38 @@ public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping> {
         this.setTClass(UserGroupMapping.class);
     }
 
-    @Override
-    public boolean storeObject(UserGroupMapping object) {
+    public List<UserGroupMapping> getByGroupId(String groupId) {
+        ResultSet rs = executeQuery("SELECT * FROM usergroupmappings WHERE groupId = ?", groupId);
+        return getObjectsFromResultSet(rs);
+    }
 
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO usergroupmappings "
-                                            + "(username, groupId)"
-                                            + " VALUES "
-                                            + "(?,?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a user profile: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<UserGroupMapping> getByUsername(String username) {
+        ResultSet rs = executeQuery("SELECT * FROM usergroupmappings WHERE username = ?", username);
+        return getObjectsFromResultSet(rs);
     }
 
-    @Override
-    public boolean deleteObject(StatementList constraints) {
+    public Optional<UserGroupMapping> getByGroupIdAndUsername(String groupId, String username) {
+        // TODO The primary key should be (groupId, username)
+        String query = "SELECT * FROM usergroupmappings WHERE groupId = ? AND username = ?";
+        List<String> params = List.of(groupId, username);
+        ResultSet rs = executeQuery(query, params);
+        return getFirstObjectFromResultSet(rs);
+    }
 
-        String username = constraints.getStatements().get(0).getValue();
-        String groupId = constraints.getStatements().get(1).getValue();
-        SQLConnection connection = DataStore.connectionPool.getConnection();
+    @Override
+    public boolean storeObject(UserGroupMapping object) {
+        String query =
+                "INSERT INTO usergroupmappings " + "(username, groupId)" + " VALUES " + "(?, ?)";
+        return executeInsert(query, object);
+    }
 
-        try {
-            if (username.equals("*")) {
-                PreparedStatement ps =
-                        connection
-                                .getConnection()
-                                .prepareStatement(
-                                        "DELETE FROM usergroupmappings WHERE groupId = ?");
-                ps.setString(1, groupId);
-                return ps.executeUpdate() != 0;
-            } else {
-                PreparedStatement ps =
-                        connection
-                                .getConnection()
-                                .prepareStatement(
-                                        "DELETE FROM usergroupmappings WHERE username = ? AND groupId = ?");
-                ps.setString(1, username);
-                ps.setString(2, groupId);
-                return ps.executeUpdate() != 0;
-            }
-        } catch (SQLException e) {
-            log.error("An error has occurred while trying to delete a group member: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
+    public boolean deleteObject(String username, String groupId) {
+        if (username.equals("*")) {
+            String query = "DELETE FROM usergroupmappings WHERE groupId = ?";
+            return executeUpdate(query, List.of(groupId));
         }
+
+        String query = "DELETE FROM usergroupmappings WHERE username = ? AND groupId = ?";
+        return executeUpdate(query, List.of(username, groupId));
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
index fd025a6347bd26ec3a40a60a0b53d2a59012134b..242c59accdb3642156c2dd58d722db8fb12940a1 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
@@ -25,65 +25,93 @@ package net.jami.datastore.dao;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.UserProfile;
 
-import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class UserProfileDao extends AbstractDao<UserProfile> {
 
-    // Fis this to include the fields from AD/LDAP.
+    // Fix this to include the fields from AD/LDAP.
     public UserProfileDao() {
         this.setTableName("local_directory");
         this.setTClass(UserProfile.class);
     }
 
-    @Override
-    public boolean storeObject(UserProfile object) {
+    public void insertIfNotExists(UserProfile userProfile) throws SQLException {
+        String query =
+                "INSERT INTO local_directory"
+                        + " (username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)"
+                        + " SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
+                        + " FROM local_directory"
+                        + " WHERE NOT EXISTS (SELECT 1 FROM local_directory WHERE username = ?)";
+
+        List<String> params = new ArrayList<>();
+        params.add(userProfile.getUsername());
+        params.add(userProfile.getFirstName());
+        params.add(userProfile.getLastName());
+        params.add(userProfile.getEmail());
+        params.add(userProfile.getProfilePicture());
+        params.add(userProfile.getOrganization());
+        params.add(userProfile.getPhoneNumber());
+        params.add(userProfile.getPhoneNumberExtension());
+        params.add(userProfile.getFaxNumber());
+        params.add(userProfile.getMobileNumber());
+        params.add(userProfile.getUsername());
+
+        this.executeUpdate(query, params);
+    }
+
+    public List<UserProfile> getAllUserProfile() {
+        ResultSet rs = executeQuery("SELECT * FROM local_directory");
+        return getObjectsFromResultSet(rs);
+    }
 
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "INSERT INTO local_directory "
-                                            + "(username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)"
-                                            + " VALUES "
-                                            + "(?,?,?,?,?,?,?,?,?,?)");
-            ps = object.getInsert(ps);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to store a user profile: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public List<UserProfile> searchUsername(String username) {
+        String query = "SELECT * FROM local_directory WHERE username LIKE ?";
+        ResultSet rs = executeQuery(query, username + "%");
+        return getObjectsFromResultSet(rs);
+    }
+
+    public List<UserProfile> searchFullName(String name) {
+        String query = "SELECT * FROM local_directory WHERE firstName LIKE ? OR lastName ?";
+        name = name + "%";
+        ResultSet rs = executeQuery(query, List.of(name, name));
+        return getObjectsFromResultSet(rs);
+    }
+
+    public Optional<UserProfile> getByUsername(String username) {
+        ResultSet rs = executeQuery("SELECT * FROM local_directory WHERE username = ?", username);
+        return getFirstObjectFromResultSet(rs);
     }
 
     @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
+    public boolean storeObject(UserProfile object) {
+        String query =
+                "INSERT INTO local_directory "
+                        + "(firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber, username)"
+                        + " VALUES "
+                        + "(?,?,?,?,?,?,?,?,?,?)";
+        return executeInsert(query, object);
+    }
 
-        SQLConnection connection = DataStore.connectionPool.getConnection();
-        try {
-            PreparedStatement ps =
-                    connection
-                            .getConnection()
-                            .prepareStatement(
-                                    "UPDATE local_directory SET firstname = ?, lastName = ?, email = ?, profilePicture = ?, organization = ?, phoneNumber = ?, phoneNumberExtension = ?, faxNumber = ?, mobileNumber = ? WHERE username = ?");
-            for (int i = 1; i < update.getStatements().size(); i++) {
-                ps.setString(i, update.getStatements().get(i).getValue());
-            }
-            ps.setString(update.getStatements().size(), update.getStatements().get(0).getValue());
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a user profile: " + e);
-            return false;
-        } finally {
-            DataStore.connectionPool.returnConnection(connection);
-        }
+    public boolean updateUserProfile(UserProfile userProfile) {
+        String query =
+                "UPDATE local_directory SET"
+                        + " firstname = ?,"
+                        + " lastName = ?,"
+                        + " email = ?,"
+                        + " profilePicture = ?,"
+                        + " organization = ?,"
+                        + " phoneNumber = ?,"
+                        + " phoneNumberExtension = ?,"
+                        + " faxNumber = ?,"
+                        + " mobileNumber = ?"
+                        + " WHERE username = ?";
+        return executeInsert(query, userProfile);
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/main/DataStore.java b/datastore/src/main/java/net/jami/datastore/main/DataStore.java
index 507cafafd32087358ce6e020f844ba60eb7a2e52..80e9491e47102073eea3d4a22227900c715ae015 100644
--- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java
+++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java
@@ -28,7 +28,6 @@ import lombok.Setter;
 import net.jami.datastore.dao.ContactDao;
 import net.jami.datastore.dao.DeviceDao;
 import net.jami.datastore.dao.GroupDao;
-import net.jami.datastore.dao.JwtDao;
 import net.jami.datastore.dao.PolicyDao;
 import net.jami.datastore.dao.SystemDao;
 import net.jami.datastore.dao.UserDao;
@@ -37,8 +36,6 @@ import net.jami.datastore.dao.UserProfileDao;
 import net.jami.jams.common.authentication.AuthenticationSource;
 import net.jami.jams.common.authentication.AuthenticationSourceInfo;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.dao.connectivity.ConnectionPool;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.objects.user.UserProfile;
@@ -61,7 +58,6 @@ public class DataStore implements AuthenticationSource {
     private DeviceDao deviceDao;
     private SystemDao systemDao;
     private ContactDao contactDao;
-    private JwtDao jwtDao;
     private UserProfileDao userProfileDao;
     private UserGroupMappingsDao userGroupMappingsDao;
     public static final Integer RESULTS_PER_PAGE = 24;
@@ -78,19 +74,10 @@ public class DataStore implements AuthenticationSource {
         deviceDao = new DeviceDao();
         systemDao = new SystemDao();
         contactDao = new ContactDao();
-        jwtDao = new JwtDao();
         userProfileDao = new UserProfileDao();
         userGroupMappingsDao = new UserGroupMappingsDao();
     }
 
-    public boolean userExists(String username) {
-        StatementList statementList = new StatementList();
-        StatementElement statementElement = new StatementElement("username", "=", username, "");
-        statementList.addStatement(statementElement);
-        List<User> userList = userDao.getObjects(statementList);
-        return (userList.size() == 1);
-    }
-
     @Override
     public boolean createUser(User user) {
         return userDao.storeObject(user);
@@ -101,20 +88,17 @@ public class DataStore implements AuthenticationSource {
             String queryString, String field, Optional<Integer> page) {
         List<UserProfile> userList;
 
-        if (!queryString.equals("*")) {
-            StatementList statementList = new StatementList();
-            String startQueryString = queryString.concat("%");
+        if (queryString.equals("*")) {
+            userList = userProfileDao.getAllUserProfile();
+        } else {
             if (field.equals("LOGON_NAME")) {
-                statementList.addStatement(
-                        new StatementElement("username", "LIKE", startQueryString, ""));
+                userList = userProfileDao.searchUsername(queryString);
             } else if (field.equals("FULL_TEXT_NAME")) {
-                statementList.addStatement(
-                        new StatementElement("firstName", "LIKE", startQueryString, "OR"));
-                statementList.addStatement(
-                        new StatementElement("lastName", "LIKE", startQueryString, ""));
+                userList = userProfileDao.searchFullName(queryString);
+            } else {
+                throw new IllegalArgumentException("Invalid field");
             }
-            userList = userProfileDao.getObjects(statementList);
-        } else userList = userProfileDao.getObjects(null);
+        }
 
         if (userList == null) userList = new ArrayList<>();
 
@@ -137,11 +121,7 @@ public class DataStore implements AuthenticationSource {
 
     @Override
     public UserProfile getUserProfile(String username) {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", username, ""));
-        List<UserProfile> userList = userProfileDao.getObjects(statementList);
-        if (userList.size() != 1) return null;
-        else return userList.get(0);
+        return userProfileDao.getByUsername(username).orElse(null);
     }
 
     @Override
@@ -150,26 +130,7 @@ public class DataStore implements AuthenticationSource {
     }
 
     public boolean updateUserProfile(UserProfile userProfile) {
-
-        StatementList update = new StatementList();
-        update.addStatement(new StatementElement("username", "=", userProfile.getUsername(), ""));
-        update.addStatement(new StatementElement("firstName", "=", userProfile.getFirstName(), ""));
-        update.addStatement(new StatementElement("lastName", "=", userProfile.getLastName(), ""));
-        update.addStatement(new StatementElement("email", "=", userProfile.getEmail(), ""));
-        update.addStatement(
-                new StatementElement("profilePicture", "=", userProfile.getProfilePicture(), ""));
-        update.addStatement(
-                new StatementElement("organization", "=", userProfile.getOrganization(), ""));
-        update.addStatement(
-                new StatementElement("phoneNumber", "=", userProfile.getPhoneNumber(), ""));
-        update.addStatement(
-                new StatementElement(
-                        "phoneNumberExtension", "=", userProfile.getPhoneNumberExtension(), ""));
-        update.addStatement(new StatementElement("faxNumber", "=", userProfile.getFaxNumber(), ""));
-        update.addStatement(
-                new StatementElement("mobileNumber", "=", userProfile.getMobileNumber(), ""));
-
-        return userProfileDao.updateObject(update, null);
+        return userProfileDao.updateUserProfile(userProfile);
     }
 
     public boolean updateUserCertificate(User user) {
@@ -179,12 +140,10 @@ public class DataStore implements AuthenticationSource {
 
     @Override
     public boolean authenticate(String username, String password) {
-        StatementList statementList = new StatementList();
-        StatementElement statementElement = new StatementElement("username", "=", username, "");
-        statementList.addStatement(statementElement);
-        List<User> userList = userDao.getObjects(statementList);
-        if (userList.size() != 1 || userList.get(0).getPassword() == null) return false;
-        return userList.get(0).getPassword().equals(password);
+        return userDao.getByUsername(username)
+                .map(user -> user.getPassword())
+                .orElse("")
+                .equals(password);
     }
 
     @Override
diff --git a/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java b/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java
index 5d465c9aa573bbd79c8c8452027dfd88926044de..dcf39d91aeb5528322351a79fc58bc4e9d30efd4 100644
--- a/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java
+++ b/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java
@@ -26,8 +26,6 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
@@ -87,9 +85,7 @@ class DAOTest {
         UserDao userDAO = new UserDao();
         userDAO.storeObject(user);
 
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", "fsidokhine", ""));
-        User user1 = userDAO.getObjects(statementList).get(0);
+        User user1 = userDAO.getByUsername("fsidokhine").get();
         Assertions.assertNotNull(user1);
         Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.ADMIN);
     }
@@ -110,9 +106,7 @@ class DAOTest {
         UserDao userDAO = new UserDao();
         userDAO.storeObject(user);
 
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", "TestUser", ""));
-        User user1 = userDAO.getObjects(statementList).get(0);
+        User user1 = userDAO.getByUsername("TestUser").get();
         Assertions.assertNotNull(user1);
         Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.USER);
 
@@ -121,7 +115,7 @@ class DAOTest {
                 X509Utils.getPEMStringFromCertificate(
                         X509Utils.getCertificateFromPEMString(refreshedCertificate)));
 
-        User user2 = userDAO.getObjects(statementList).get(0);
+        User user2 = userDAO.getByUsername("TestUser").get();
         Assertions.assertNotEquals(user1.getCertificate(), user2.getCertificate());
     }
 
@@ -135,9 +129,7 @@ class DAOTest {
         DeviceDao deviceDAO = new DeviceDao();
         deviceDAO.storeObject(device);
 
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("owner", "=", "fsidokhine", ""));
-        Device device1 = deviceDAO.getObjects(statementList).get(0);
+        Device device1 = deviceDAO.getByOwner("fsidokhine").get(0);
         Assertions.assertNotNull(device1);
     }
 
@@ -155,9 +147,7 @@ class DAOTest {
         UserDao userDAO = new UserDao();
         userDAO.storeObject(user);
 
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", "admin", ""));
-        User user1 = userDAO.getObjects(statementList).get(0);
+        User user1 = userDAO.getByUsername("admin").get();
         Assertions.assertNotNull(user1);
         Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.ADMIN);
     }
diff --git a/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java b/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java
index ce44aa428be7f1a41413e26f87aa3236c00eb74b..765fe786c83ad29c8910c7aaa83da2419cac3d91 100644
--- a/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java
+++ b/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java
@@ -27,8 +27,6 @@ import lombok.extern.slf4j.Slf4j;
 import net.jami.datastore.main.DataStore;
 import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.common.authmodule.AuthenticationModule;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.jami.NameLookupResponse;
 import net.jami.jams.common.jami.NameRegistrationRequest;
 import net.jami.jams.common.jami.NameServer;
@@ -37,6 +35,7 @@ import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.objects.user.UserProfile;
 
 import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class LocalNameServer implements NameServer {
@@ -62,12 +61,8 @@ public class LocalNameServer implements NameServer {
 
     @Override
     public NameLookupResponse getAddressFromName(String username) {
-        NameLookupResponse nameLookupResponse = null;
-        StatementList statementList = new StatementList();
-        StatementElement statementElement = new StatementElement("username", "=", username, "");
-        statementList.addStatement(statementElement);
-        List<User> results = dataStore.getUserDao().getObjects(statementList);
-        if (results.size() == 0) {
+        Optional<User> result = dataStore.getUserDao().getByUsername(username);
+        if (result.isEmpty()) {
             // Reattempt resolution via directory lookups.
             final User user = new User();
             for (AuthModuleKey key : authenticationModule.getAuthSources().keySet()) {
@@ -87,22 +82,19 @@ public class LocalNameServer implements NameServer {
             }
             if (user.getUsername() == null) return null;
             // resolve again in the database to be sure.
-            results = dataStore.getUserDao().getObjects(statementList);
-            if (results.size() == 0) return null;
+            result = dataStore.getUserDao().getByUsername(username);
+            if (result.isEmpty()) return null;
         }
-        nameLookupResponse = new NameLookupResponse();
-        nameLookupResponse.setName(results.get(0).getUsername());
-        nameLookupResponse.setAddr(results.get(0).getJamiId());
+        NameLookupResponse nameLookupResponse = new NameLookupResponse();
+        nameLookupResponse.setName(result.get().getUsername());
+        nameLookupResponse.setAddr(result.get().getJamiId());
         return nameLookupResponse;
     }
 
     @Override
     public String getNameFromAddress(String address) {
-        StatementList statementList = new StatementList();
-        StatementElement statementElement = new StatementElement("jamiId", "=", address, "");
-        statementList.addStatement(statementElement);
-        List<User> results = dataStore.getUserDao().getObjects(statementList);
-        if (results.size() == 0) return null;
+        List<User> results = dataStore.getUserDao().getByJamiId(address);
+        if (results.isEmpty()) return null;
         return results.get(0).getUsername();
     }
 
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
index d176275bbf3b8af3557a05e4259edaabe4bf6315..86f7437f086229b7cc8e57dfe468d85c623f6259 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
@@ -56,11 +56,10 @@ public class UserBuilder {
             keyPairGenerator.initialize(4096);
             KeyPair keyPair = keyPairGenerator.generateKeyPair();
 
-            user.getX509Fields()
-                    .setUid(
-                            Hex.encodeHexString(
-                                    MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1)
-                                            .digest(keyPair.getPublic().getEncoded())));
+            byte[] digest =
+                    MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1)
+                            .digest(keyPair.getPublic().getEncoded());
+            user.getX509Fields().setUid(Hex.encodeHexString(digest));
 
             X509v3CertificateBuilder builder =
                     new X509v3CertificateBuilder(
@@ -90,13 +89,13 @@ public class UserBuilder {
     }
 
     public static User refreshUser(User user, long userLifeTime) {
-        try {
-            long now = System.currentTimeMillis();
-
-            user.setX509Fields(new X509Fields());
-            user.getX509Fields().setCommonName(user.getUsername());
-            user.getX509Fields().setUid(user.getJamiId());
+        long now = System.currentTimeMillis();
+        X509Fields x509 = new X509Fields();
+        x509.setCommonName(user.getUsername());
+        x509.setUid(user.getJamiId());
+        user.setX509Fields(x509);
 
+        try {
             X509v3CertificateBuilder builder =
                     new X509v3CertificateBuilder(
                             new JcaX509CertificateHolder(JamsCA.CA.getCertificate()).getSubject(),
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java
index 3b064f6aac7008cca130657d06b9daeb9c3bf60a..463f7081dd61f70688bc5c4c04a75a1b155ea5f3 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java
@@ -96,7 +96,7 @@ public class OCSPWorker extends X509Worker<String> {
             if (validateRequest(ocspRequest) != null)
                 throw new OCSPException(
                         "Request is not valid"); // this means the request is invalid and we should
-                                                 // notify the client.
+            // notify the client.
             // If the request was valid, we move on to other things.
             BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(responderID);
             // Add appropriate extensions
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java
deleted file mode 100644
index b89eb731ba9a7d819a416300cfb2fdf109f129b9..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import net.jami.jams.common.dao.connectivity.SQLConnection;
-
-import java.sql.PreparedStatement;
-
-public class DeleteStatementBuilder {
-
-    public static PreparedStatement buildStatement(
-            String table, StatementList statementElements, SQLConnection connection)
-            throws Exception {
-        PreparedStatement ps = null;
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append("DELETE FROM ").append(table);
-        if (statementElements != null) {
-            stringBuilder.append(" WHERE ");
-            for (StatementElement statementElement : statementElements.getStatements()) {
-                stringBuilder
-                        .append(statementElement.getColumn())
-                        .append(" ")
-                        .append(statementElement.getOperator())
-                        .append(" ")
-                        .append("?")
-                        .append(" ")
-                        .append(statementElement.getNextStatementRelation())
-                        .append(" ");
-            }
-            ps = connection.getConnection().prepareStatement(stringBuilder.toString());
-            int i = 1;
-            for (StatementElement statementElement : statementElements.getStatements()) {
-                ps.setString(i, statementElement.getValue());
-                i++;
-            }
-        } else {
-            ps = connection.getConnection().prepareStatement(stringBuilder.toString());
-        }
-        return ps;
-    }
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java
deleted file mode 100644
index cd591e9c794b086550405c7116e30b73cee653c0..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import net.jami.jams.common.dao.connectivity.SQLConnection;
-
-import java.sql.PreparedStatement;
-
-public class SelectStatementBuilder {
-
-    public static PreparedStatement buildStatement(
-            String table,
-            StatementList statementElements,
-            StatementConstraints statementConstraints,
-            SQLConnection connection)
-            throws Exception {
-        PreparedStatement ps = null;
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append("SELECT * FROM ").append(table);
-        if (statementElements != null) {
-            stringBuilder.append(" WHERE ");
-            for (StatementElement statementElement : statementElements.getStatements()) {
-
-                stringBuilder
-                        .append("lower(" + statementElement.getColumn() + ")")
-                        .append(" ")
-                        .append(statementElement.getOperator())
-                        .append(" ")
-                        .append("?")
-                        .append(" ")
-                        .append(statementElement.getNextStatementRelation())
-                        .append(" ");
-            }
-            ps = connection.getConnection().prepareStatement(stringBuilder.toString());
-            int i = 1;
-            for (StatementElement statementElement : statementElements.getStatements()) {
-                ps.setString(i, (statementElement.getValue()).toLowerCase());
-                i++;
-            }
-        } else {
-            if (statementConstraints != null) {
-                stringBuilder
-                        .append(" LIMIT ")
-                        .append(statementConstraints.getRowCount())
-                        .append(" OFFSET ")
-                        .append(statementConstraints.getOffset());
-            }
-            ps = connection.getConnection().prepareStatement(stringBuilder.toString());
-        }
-        return ps;
-    }
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java
deleted file mode 100644
index f2f2294c1c1871f3b976f6397c45bbefc602b109..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class StatementConstraints {
-
-    private Long rowCount;
-    private Long offset;
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java
deleted file mode 100644
index 6e1446b2bace8e0f66368d199a22f51d4f18c693..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-@Getter
-@Setter
-@AllArgsConstructor
-@NoArgsConstructor
-public class StatementElement {
-    private String column;
-    private String operator;
-    private String value;
-    private String nextStatementRelation;
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java
deleted file mode 100644
index 8767fda06cd9d49eefa355534e4273028cb7d093..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Getter
-@Setter
-public class StatementList {
-
-    private List<StatementElement> statements = new ArrayList<>();
-
-    public void addStatement(StatementElement statementElement) {
-        statements.add(statementElement);
-    }
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java
deleted file mode 100644
index 8743e00efc85c9704959e15bec92be9c62cee0f5..0000000000000000000000000000000000000000
--- a/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Authors: William Enright <william.enright@savoirfairelinux.com>
- *          Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com>
- *          Johnny Flores <johnny.flores@savoirfairelinux.com>
- *          Mohammed Raza <mohammed.raza@savoirfairelinux.com>
- *          Felix Sidokhine <felix.sidokhine@savoirfairelinux.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-package net.jami.jams.common.dao;
-
-import net.jami.jams.common.dao.connectivity.SQLConnection;
-
-import java.sql.PreparedStatement;
-
-public class UpdateStatementBuilder {
-    public static PreparedStatement buildStatement(
-            String table,
-            StatementList updateElements,
-            StatementList conditionalElements,
-            SQLConnection connection)
-            throws Exception {
-        PreparedStatement ps = null;
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append("UPDATE ").append(table).append(" SET ");
-        for (int i = 0; i < updateElements.getStatements().size(); i++) {
-            StatementElement statementElement = updateElements.getStatements().get(i);
-            stringBuilder.append(statementElement.getColumn()).append(" = ").append("?");
-            if (i != updateElements.getStatements().size() - 1) stringBuilder.append(",");
-        }
-        stringBuilder.append(" WHERE ");
-        for (StatementElement statementElement : conditionalElements.getStatements()) {
-            stringBuilder
-                    .append(statementElement.getColumn())
-                    .append(" ")
-                    .append(statementElement.getOperator())
-                    .append(" ")
-                    .append("?")
-                    .append(" ")
-                    .append(statementElement.getNextStatementRelation());
-        }
-        ps = connection.getConnection().prepareStatement(stringBuilder.toString());
-        // Now we have to feed this all the elements it should have.
-        updateElements.getStatements().addAll(conditionalElements.getStatements());
-        int i = 1;
-        for (StatementElement statementElement : updateElements.getStatements()) {
-            ps.setString(i, statementElement.getValue());
-            i++;
-        }
-        return ps;
-    }
-}
diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
index 609fa345c2de89aff70b1105218191b3417c9a19..fdfbb1afda08d7208bfd46352a38e45e34a48438 100644
--- a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
+++ b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
@@ -122,16 +122,16 @@ public class UserProfile implements DatabaseObject {
 
     @Override
     public PreparedStatement getInsert(PreparedStatement ps) throws Exception {
-        ps.setString(1, username);
-        ps.setString(2, firstName);
-        ps.setString(3, lastName);
-        ps.setString(4, email);
-        ps.setString(5, profilePicture);
-        ps.setString(6, organization);
-        ps.setString(7, phoneNumber);
-        ps.setString(8, phoneNumberExtension);
-        ps.setString(9, faxNumber);
-        ps.setString(10, mobileNumber);
+        ps.setString(1, firstName);
+        ps.setString(2, lastName);
+        ps.setString(3, email);
+        ps.setString(4, profilePicture);
+        ps.setString(5, organization);
+        ps.setString(6, phoneNumber);
+        ps.setString(7, phoneNumberExtension);
+        ps.setString(8, faxNumber);
+        ps.setString(9, mobileNumber);
+        ps.setString(10, username);
         return ps;
     }
 
diff --git a/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java b/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java
index 2a953419e1229e2f1ab4d3f3bc7586a286e228e6..601a34f3f015f80750a012a2f52705b68494bb11 100644
--- a/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java
+++ b/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java
@@ -25,8 +25,8 @@ class ContactTest {
     @Test
     public void deserialize() {
         String str =
-                "[{\"uri\":\"tcp://def@local\",\"added\":1594742298377,\"banned\":false,\"confirmed\":true,\"confirmed\":6a61013979964f70c8fb9183a8b238d58a1846ed},"
-                        + "{\"uri\":\"tcp://abc@19293.com\",\"removed\":1594742298377,\"banned\":true,\"confirmed\":true,\"confirmed\":2b61024119964f70c8fb9183a8b238d58a1846ed}]";
+                "[{\"uri\":\"tcp://def@local\",\"added\":1594742298377,\"banned\":false,\"confirmed\":true,\"conversationId\":\"6a61013979964f70c8fb9183a8b238d58a1846ed\"},"
+                        + "{\"uri\":\"tcp://abc@19293.com\",\"removed\":1594742298377,\"banned\":true,\"confirmed\":true,\"conversationId\":\"2b61024119964f70c8fb9183a8b238d58a1846e\"}]";
         Contact[] contacts = JsonIterator.deserialize(str, Contact[].class);
         Assertions.assertEquals(2, contacts.length);
     }
diff --git a/jams-server/src/main/java/net/jami/jams/server/Server.java b/jams-server/src/main/java/net/jami/jams/server/Server.java
index 40488b8ca56d009ab80012f362c2344c83c5a081..4a750d075bcc53ab1c5399f95870d09d5bd4169d 100644
--- a/jams-server/src/main/java/net/jami/jams/server/Server.java
+++ b/jams-server/src/main/java/net/jami/jams/server/Server.java
@@ -46,7 +46,7 @@ import net.jami.jams.server.startup.CryptoEngineLoader;
 import net.jami.jams.server.update.JAMSUpdater;
 import net.jami.jams.server.update.UpdateInterface;
 
-import java.awt.*;
+import java.awt.Desktop;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
index ccc9a9123045fcf460b4c5c9474b13f40bbe54a4..ed742f18b53f7bf110ee941ee14985c6aa0ce4d2 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
@@ -32,21 +32,15 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.authmodule.UserAuthenticationModule;
 import net.jami.jams.common.authmodule.AuthModuleKey;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.requests.DeviceRegistrationRequest;
 import net.jami.jams.common.objects.responses.DeviceRegistrationResponse;
-import net.jami.jams.common.objects.user.Group;
-import net.jami.jams.common.objects.user.Policy;
 import net.jami.jams.common.objects.user.User;
-import net.jami.jams.common.objects.user.UserGroupMapping;
 import net.jami.jams.common.objects.user.UserProfile;
 import net.jami.jams.dht.DeviceReceiptGenerator;
 
 import java.security.cert.X509Certificate;
 import java.util.Date;
-import java.util.List;
 import java.util.Optional;
 
 @Slf4j
@@ -55,9 +49,7 @@ public class RegisterDeviceFlow {
     public static DeviceRegistrationResponse registerDevice(
             String username, DeviceRegistrationRequest registrationRequest) {
         try {
-            StatementList statementList = new StatementList();
-            statementList.addStatement(new StatementElement("username", "=", username, ""));
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
+            User user = dataStore.getUserDao().getByUsername(username).orElseThrow();
 
             UserProfile userProfile =
                     userAuthenticationModule
@@ -66,11 +58,6 @@ public class RegisterDeviceFlow {
                             .searchUserProfiles(username, "LOGON_NAME", Optional.empty())
                             .get(0);
 
-            if (user == null) {
-                log.error(
-                        "Tried to enroll a device, but could not find a user, this is impossible!");
-            }
-
             // Renew user certificate if expired with same private key
             if (!user.getCertificate().getNotAfter().after(new Date())) {
                 user = UserAuthenticationModule.certificateAuthority.getRefreshedCertificate(user);
@@ -88,10 +75,8 @@ public class RegisterDeviceFlow {
             }
             dataStore.getDeviceDao().storeObject(device);
 
-            Group group = getGroupByUsername(username);
-
             DeviceRegistrationResponse response = new DeviceRegistrationResponse();
-            String policyData = getPolicyData(group);
+            String policyData = getPolicyData(username);
             if (policyData != null) {
                 response.setPolicyData(policyData);
             }
@@ -124,39 +109,17 @@ public class RegisterDeviceFlow {
         }
     }
 
-    public static Group getGroupByUsername(String username) {
-        Group group = new Group();
-
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", username, ""));
-        List<UserGroupMapping> userGroupMappings =
-                dataStore.getUserGroupMappingsDao().getObjects(statementList);
-
-        if (userGroupMappings != null && !userGroupMappings.isEmpty()) {
-            UserGroupMapping mapping = userGroupMappings.get(0);
-            statementList = new StatementList();
-            statementList.addStatement(new StatementElement("id", "=", mapping.getGroupId(), ""));
-            group = dataStore.getGroupDao().getObjects(statementList).get(0);
-        }
-
-        return group;
-    }
-
-    public static String getPolicyData(Group group) {
-        if (!group.isEmpty() && group.hasBlueprint()) {
-            StatementElement statementElement =
-                    new StatementElement("name", "=", group.getBlueprint(), "");
-            StatementList statementList = new StatementList();
-            statementList.addStatement(statementElement);
-            try {
-                Policy policy = dataStore.getPolicyDao().getObjects(statementList).get(0);
-                return policy.getPolicyData();
-            } catch (Exception e) {
-                log.warn(
-                        "No policy available for user - not adding a policy component to response");
-            }
+    public static String getPolicyData(String username) {
+        String policy =
+                dataStore
+                        .getPolicyDao()
+                        .getByUsername(username)
+                        .map(p -> p.getPolicyData())
+                        .orElse(null);
+        if (policy == null) {
+            log.warn("No policy available for user - not adding a policy component to response");
         }
 
-        return null;
+        return policy;
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java
index 410d2a73238cc2ad38263f41235caf1ed57f8bba..1d0a112fa41a9d9b41b97751d1b25b094e832f91 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java
@@ -27,14 +27,13 @@ import static net.jami.jams.server.Server.dataStore;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.requests.RevocationRequest;
 import net.jami.jams.common.objects.requests.RevocationType;
 import net.jami.jams.common.objects.responses.DeviceRevocationResponse;
 
 import java.math.BigInteger;
+import java.util.Optional;
 
 @Slf4j
 public class RevokeDeviceFlow {
@@ -42,17 +41,15 @@ public class RevokeDeviceFlow {
     public static DeviceRevocationResponse revokeDevice(String username, String deviceId) {
         DeviceRevocationResponse response = new DeviceRevocationResponse();
         try {
-            StatementList statementList = new StatementList();
-            StatementElement st1 = new StatementElement("owner", "=", username, "AND");
-            StatementElement st2 = new StatementElement("deviceId", "=", deviceId, "");
-            statementList.addStatement(st1);
-            statementList.addStatement(st2);
-            Device device = dataStore.getDeviceDao().getObjects(statementList).get(0);
-            if (device == null) {
+            Optional<Device> result =
+                    dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username);
+            if (result.isEmpty()) {
                 log.error("Could not find device!");
                 return null;
             }
 
+            Device device = result.get();
+
             BigInteger serialNumber = device.getCertificate().getSerialNumber();
 
             RevocationRequest request = new RevocationRequest(serialNumber, RevocationType.DEVICE);
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java
index a71932981cca339e49e9f2b44c825130f7fea04b..0b2a1c93e653788fe6b1416234a00b719efce56f 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java
@@ -27,8 +27,6 @@ import static net.jami.jams.server.Server.dataStore;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.requests.RevocationRequest;
 import net.jami.jams.common.objects.requests.RevocationType;
 import net.jami.jams.common.objects.responses.DeviceRevocationResponse;
@@ -40,10 +38,7 @@ public class RevokeUserFlow {
     public static DeviceRevocationResponse revokeUser(String username) {
         DeviceRevocationResponse response = new DeviceRevocationResponse();
         try {
-            StatementList statementList = new StatementList();
-            StatementElement st1 = new StatementElement("username", "=", username, "");
-            statementList.addStatement(st1);
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
+            User user = dataStore.getUserDao().getByUsername(username).get();
             if (user == null) {
                 log.error("Could not find user!");
                 return null;
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java
index 349402305608f62781a3f310dbbbaf7967482a74..1ba1ba3c9e7aab92b46fe6f5184b7576f1aaacb3 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java
@@ -37,15 +37,13 @@ import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.authmodule.AuthTokenResponse;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler;
 import net.jami.jams.server.servlets.api.auth.login.LoginRequest;
 
 import java.io.IOException;
 import java.security.cert.X509Certificate;
-import java.util.List;
+import java.util.Optional;
 
 @WebServlet("/api/login")
 // This method returns the token which is used for all the next calls to the
@@ -86,19 +84,15 @@ public class LoginServlet extends HttpServlet {
                             req.getInputStream().readAllBytes(), LoginRequest.class);
             if (object.getUsername() != null && object.getPassword() != null) {
                 res = processUsernamePasswordAuth(object.getUsername(), object.getPassword());
-                StatementList statementList = new StatementList();
-                StatementElement statementElement =
-                        new StatementElement("username", "=", object.getUsername(), "");
-                statementList.addStatement(statementElement);
-                List<User> users = dataStore.getUserDao().getObjects(statementList);
-                if (users.size() != 0
+                Optional<User> user = dataStore.getUserDao().getByUsername(object.getUsername());
+                if (user.isPresent()
                         && certificateAuthority.getLatestCRL().get() != null
-                        && !users.get(0).getAccessLevelName().equals("ADMIN")
+                        && !user.get().getAccessLevelName().equals("ADMIN")
                         && certificateAuthority
                                         .getLatestCRL()
                                         .get()
                                         .getRevokedCertificate(
-                                                users.get(0).getCertificate().getSerialNumber())
+                                                user.get().getCertificate().getSerialNumber())
                                 != null) {
                     TomcatCustomErrorHandler.sendCustomError(
                             resp, 401, "Invalid credentials provided!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java
index fd1df0c1b1b4965680c26f621ba8fe1e3041be5c..6149f3873ff28e93b7de044cfb115ffe97d3bfbd 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java
@@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.contacts.Contact;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler;
@@ -69,10 +67,8 @@ public class ContactServlet extends HttpServlet {
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getParameter("username"), ""));
-        List<Contact> contactList = dataStore.getContactDao().getObjects(statementList);
+        List<Contact> contactList =
+                dataStore.getContactDao().getByOwner(req.getParameter("username"));
         resp.getOutputStream().write(JsonStream.serialize(contactList).getBytes());
     }
 
@@ -96,6 +92,7 @@ public class ContactServlet extends HttpServlet {
         Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A");
         String res = s.hasNext() ? s.next() : "";
         final JSONObject obj = new JSONObject(res);
+
         Contact contact = new Contact();
         // TODO: Replace with mergetool.
         contact.setDisplayName(obj.get("displayName").toString());
@@ -103,13 +100,13 @@ public class ContactServlet extends HttpServlet {
         contact.setStatus('A');
         contact.setOwner(req.getParameter("username"));
         contact.setUri(obj.get("uri").toString());
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getParameter("username"), ""));
-        List<Contact> localList = dataStore.getContactDao().getObjects(statementList);
+
+        List<Contact> localList =
+                dataStore.getContactDao().getByOwner(req.getParameter("username"));
         List<Contact> remoteList = new ArrayList<>();
         remoteList.add(contact);
         List<Contact> result = ContactMerger.mergeContacts(localList, remoteList);
+
         if (dataStore.getContactDao().storeContactList(result)) resp.setStatus(200);
         else
             TomcatCustomErrorHandler.sendCustomError(
@@ -131,22 +128,9 @@ public class ContactServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getParameter("username"), "AND"));
-        statementList.addStatement(new StatementElement("uri", "=", req.getParameter("uri"), ""));
-        /*
-         * List<Contact> remoteList =
-         * dataStore.getContactDao().getObjects(statementList);
-         * remoteList.get(0).setStatus('D');
-         * remoteList.get(0).setTimestamp(System.currentTimeMillis()); statementList =
-         * new StatementList(); statementList.addStatement(new
-         * StatementElement("owner","=",req.getParameter("username").toString(),""));
-         * List<Contact> localList =
-         * dataStore.getContactDao().getObjects(statementList); List<Contact> result =
-         * ContactMerger.mergeContacts(localList,remoteList);
-         */
-        if (dataStore.getContactDao().deleteObject(statementList)) resp.setStatus(200);
+        String owner = req.getParameter("username");
+        String uri = req.getParameter("uri");
+        if (dataStore.getContactDao().deleteObject(owner, uri)) resp.setStatus(200);
         else
             TomcatCustomErrorHandler.sendCustomError(
                     resp, 500, "could not delete a contact due to server-side error");
@@ -170,16 +154,16 @@ public class ContactServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getParameter("username"), ""));
-        List<Contact> localList = dataStore.getContactDao().getObjects(statementList);
+        List<Contact> localList =
+                dataStore.getContactDao().getByOwner(req.getParameter("username"));
         List<Contact> remoteList =
                 Arrays.asList(
                         JsonIterator.deserialize(
                                 req.getInputStream().readAllBytes(), Contact[].class));
+
         remoteList.forEach(contact -> contact.setOwner(req.getParameter("username")));
         List<Contact> result = ContactMerger.mergeContacts(localList, remoteList);
+
         if (!dataStore.getContactDao().storeContactList(result))
             TomcatCustomErrorHandler.sendCustomError(resp, 500, "Could not store contacts!");
         else resp.getOutputStream().write(JsonStream.serialize(result).getBytes());
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java
index 100bf578d6759d04fa0b782b5f42c34d6594e4f3..656f3c2295a7992f6ac9738320636514784cf7e5 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java
@@ -33,8 +33,7 @@ import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.responses.DeviceRevocationResponse;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.server.core.workflows.RevokeDeviceFlow;
@@ -51,16 +50,9 @@ public class DeviceServlet extends HttpServlet {
             throws ServletException, IOException {
         String username = req.getParameter("username");
         String deviceId = req.getParameter("deviceId");
-        StatementList statementList = new StatementList();
-        StatementElement st1 = new StatementElement("owner", "=", username, "AND");
-        StatementElement st2 = new StatementElement("deviceId", "=", deviceId, "");
-        statementList.addStatement(st1);
-        statementList.addStatement(st2);
-        resp.getOutputStream()
-                .write(
-                        JsonStream.serialize(
-                                        dataStore.getDeviceDao().getObjects(statementList).get(0))
-                                .getBytes());
+        Device device =
+                dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username).orElseThrow();
+        resp.getOutputStream().write(JsonStream.serialize(device).getBytes());
     }
 
     // Update device data.
@@ -71,15 +63,9 @@ public class DeviceServlet extends HttpServlet {
         String username = req.getParameter("username");
         String deviceId = req.getParameter("deviceId");
         String deviceName = req.getParameter("deviceName");
-        StatementList update = new StatementList();
-        StatementElement st0 = new StatementElement("deviceName", "=", deviceName, "");
-        update.addStatement(st0);
-        StatementList constraint = new StatementList();
-        StatementElement st1 = new StatementElement("owner", "=", username, "AND");
-        StatementElement st2 = new StatementElement("deviceId", "=", deviceId, "");
-        update.addStatement(st1);
-        update.addStatement(st2);
-        if (dataStore.getDeviceDao().updateObject(update, constraint)) resp.setStatus(200);
+
+        if (dataStore.getDeviceDao().updateObject(deviceName, username, deviceId))
+            resp.setStatus(200);
         else resp.sendError(500, "could not update the device's information!");
     }
 
@@ -88,9 +74,9 @@ public class DeviceServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        DeviceRevocationResponse devResponse =
-                RevokeDeviceFlow.revokeDevice(
-                        req.getParameter("username"), req.getParameter("deviceId"));
+        String username = req.getParameter("username");
+        String deviceId = req.getParameter("deviceId");
+        DeviceRevocationResponse devResponse = RevokeDeviceFlow.revokeDevice(username, deviceId);
         if (devResponse != null)
             resp.getOutputStream().write(JsonStream.serialize(devResponse).getBytes());
         else resp.sendError(500, "An exception has occurred while trying to revoke a device!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java
index 4697c5a13b411283e179dbfe3b84bdcca5c5e072..a4b3de098e427d593196a1c9e55f67ece2b050b3 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java
@@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.user.AccessLevel;
 
@@ -53,9 +51,7 @@ public class DevicesServlet extends HttpServlet {
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         String username = req.getParameter("username");
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("owner", "=", username, ""));
-        List<Device> devices = dataStore.getDeviceDao().getObjects(statementList);
+        List<Device> devices = dataStore.getDeviceDao().getByOwner(username);
         if (certificateAuthority.getLatestCRL() != null) {
             devices.forEach(
                     device -> {
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
index 9726601219fc277455dec6f89ef40e8d96afe6c7..faba679520c30fb998e5d799e27bee402611bc8f 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
@@ -41,8 +41,6 @@ import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
 import net.jami.jams.common.authmodule.AuthModuleKey;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.objects.user.UserProfile;
@@ -97,16 +95,12 @@ public class DirectoryEntryServlet extends HttpServlet {
         // Check if he is AD/LDAP - then return a 500, because we can't update those profile datas.
         UserProfile userProfile =
                 JsonIterator.deserialize(req.getInputStream().readAllBytes(), UserProfile.class);
-        StatementList select = new StatementList();
-        StatementElement st = new StatementElement("username", "=", userProfile.getUsername(), "");
-        select.addStatement(st);
 
-        User targetUser = dataStore.getUserDao().getObjects(select).get(0);
-        select = new StatementList();
-        st = new StatementElement("username", "=", req.getAttribute("username").toString(), "");
-        select.addStatement(st);
+        String username = req.getAttribute("username").toString();
 
-        User callingUser = dataStore.getUserDao().getObjects(select).get(0);
+        User targetUser =
+                dataStore.getUserDao().getByUsername(userProfile.getUsername()).orElseThrow();
+        User callingUser = dataStore.getUserDao().getByUsername(username).orElseThrow();
 
         if (targetUser.getUserType() != AuthenticationSourceType.LOCAL) {
             resp.sendError(
@@ -117,16 +111,14 @@ public class DirectoryEntryServlet extends HttpServlet {
         if (callingUser.getAccessLevel() == AccessLevel.ADMIN
                 || (callingUser.getAccessLevel() == AccessLevel.USER
                         && callingUser.getUsername().equals(targetUser.getUsername()))) {
-            select = new StatementList();
-            select.addStatement(
-                    new StatementElement("username", "=", userProfile.getUsername(), ""));
             if (dataStore.updateUserProfile(userProfile)) resp.setStatus(200);
             else resp.sendError(500, "Could not update the users's profile information");
-        } else {
-            resp.sendError(
-                    403,
-                    "The user is either not an admin account or is attempting to edit a profile that is not his own!");
+
+            return;
         }
+        resp.sendError(
+                403,
+                "The user is either not an admin account or is attempting to edit a profile that is not his own!");
     }
 
     @Override
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
index 489de813ba62cba5657f29c594dc7e4dc7ccef95..e6e0c6686a4039022403a9b5e96f4db9be45b85b 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
@@ -14,14 +14,13 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.Group;
 
 import org.json.JSONObject;
 
 import java.io.IOException;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 @WebServlet("/api/admin/group/*")
@@ -33,18 +32,13 @@ public class GroupServlet extends HttpServlet {
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        Group singleGroup = null;
         String id = req.getPathInfo().replace("/", "");
 
-        StatementList statementList = new StatementList();
-        StatementElement st = new StatementElement("id", "=", id, "");
+        Optional<Group> singleGroup = dataStore.getGroupDao().getById(id);
 
-        statementList.addStatement(st);
-        if (!dataStore.getGroupDao().getObjects(statementList).isEmpty())
-            singleGroup = dataStore.getGroupDao().getObjects(statementList).get(0);
-
-        if (singleGroup != null) {
-            resp.getOutputStream().write(JsonStream.serialize(singleGroup).getBytes());
+        if (singleGroup.isPresent()) {
+            resp.getOutputStream()
+                    .write(JsonStream.serialize(singleGroup.orElseThrow()).getBytes());
             resp.setStatus(200);
         } else {
             log.info("No group with this id was found!");
@@ -56,7 +50,6 @@ public class GroupServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-
         String id = req.getPathInfo().replace("/", "");
 
         final JSONObject obj =
@@ -68,20 +61,7 @@ public class GroupServlet extends HttpServlet {
         String name = obj.getString("name");
         String blueprint = obj.getString("blueprint");
 
-        StatementList update = new StatementList();
-
-        StatementElement st0 = new StatementElement("id", "=", id, "");
-        update.addStatement(st0);
-
-        StatementElement st1 = new StatementElement("name", "=", name, "");
-        update.addStatement(st1);
-
-        StatementElement st2 = new StatementElement("blueprint", "=", blueprint, "");
-        update.addStatement(st2);
-
-        StatementList constraint = new StatementList();
-
-        if (dataStore.getGroupDao().updateObject(update, constraint)) resp.setStatus(200);
+        if (dataStore.getGroupDao().updateObject(id, name, blueprint)) resp.setStatus(200);
         else resp.sendError(500, "Could not update group!");
     }
 
@@ -89,20 +69,10 @@ public class GroupServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        String id = req.getPathInfo().replace("/", "");
+        String groupId = req.getPathInfo().replace("/", "");
 
-        StatementElement statementElement = new StatementElement("id", "=", id, "");
-
-        StatementList constraint = new StatementList();
-        constraint.addStatement(statementElement);
-        if (dataStore.getGroupDao().deleteObject(constraint)) {
-            StatementElement statementElement1 = new StatementElement("username", "=", "*", "");
-            StatementElement statementElement2 = new StatementElement("groupId", "=", id, "");
-            StatementList constraintMapping = new StatementList();
-            constraintMapping.addStatement(statementElement1);
-            constraintMapping.addStatement(statementElement2);
-            if (dataStore.getUserGroupMappingsDao().deleteObject(constraintMapping))
-                resp.setStatus(200);
+        if (dataStore.getGroupDao().deleteObject(groupId)) {
+            if (dataStore.getUserGroupMappingsDao().deleteObject("*", groupId)) resp.setStatus(200);
             else resp.sendError(500, "Could not delete the group mappings successfully!");
         } else {
             resp.sendError(500, "Could not delete the group successfully!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java
index 9b5d34e6ea155cac6a6590eb7d08b851973f0de7..38c7b761d1945d42cda581eb4007a026261d26ff 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java
@@ -30,7 +30,7 @@ public class GroupsServlet extends HttpServlet {
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
 
-        List<Group> groups = dataStore.getGroupDao().getObjects(null);
+        List<Group> groups = dataStore.getGroupDao().getAll();
 
         if (!groups.isEmpty()) {
             resp.getOutputStream().write(JsonStream.serialize(groups).getBytes());
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java
index 174ededdcc3af4d4d12bd2e108e65723abaa4641..06c5f0ceab1c077aefd7a4792b243745dd27165a 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java
@@ -14,13 +14,12 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.Policy;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Optional;
 
 @WebServlet("/api/admin/policy/*")
 @Slf4j
@@ -31,29 +30,26 @@ public class PolicyProfileServlet extends HttpServlet {
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-
-        List<Policy> policies;
         String name = req.getPathInfo().replace("/", "");
+        getPolicyAndSendResponse(resp, name);
+    }
 
-        if (!name.equals("*")) {
-            StatementList statementList = new StatementList();
-            StatementElement st = new StatementElement("name", "=", name, "");
-            statementList.addStatement(st);
-            if (!dataStore.getPolicyDao().getObjects(statementList).isEmpty()) {
-                resp.getOutputStream()
-                        .write(
-                                JsonStream.serialize(
-                                                dataStore
-                                                        .getPolicyDao()
-                                                        .getObjects(statementList)
-                                                        .get(0))
-                                        .getBytes());
-                resp.setStatus(200);
-            }
-        } else {
-            policies = dataStore.getPolicyDao().getObjects(null);
+    public static void getPolicyAndSendResponse(HttpServletResponse resp, String name)
+            throws IOException {
+        if (name.equals("*")) {
+            List<Policy> policies = dataStore.getPolicyDao().getAll();
             resp.getOutputStream().write(JsonStream.serialize(policies).getBytes());
             resp.setStatus(200);
+            return;
+        }
+
+        Optional<Policy> policy = dataStore.getPolicyDao().getByName(name);
+        if (policy.isPresent()) {
+            byte[] bytes = JsonStream.serialize(policy.orElseThrow()).getBytes();
+            resp.getOutputStream().write(bytes);
+            resp.setStatus(200);
+        } else {
+            resp.sendError(404, "{\"message\": \"No policy found.\"}");
         }
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java
index 09ca1d93a6ab62080f168ff62c2107c3d431c38b..c4b8369075258ab49ecdf4f65466f930f5132bb3 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java
@@ -2,8 +2,6 @@ package net.jami.jams.server.servlets.api.admin.group;
 
 import static net.jami.jams.server.Server.dataStore;
 
-import com.jsoniter.output.JsonStream;
-
 import jakarta.servlet.ServletException;
 import jakarta.servlet.annotation.WebServlet;
 import jakarta.servlet.http.HttpServlet;
@@ -14,15 +12,12 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.Policy;
 
 import org.json.JSONObject;
 
 import java.io.IOException;
-import java.util.List;
 import java.util.Scanner;
 
 @Slf4j
@@ -34,27 +29,8 @@ public class PolicyServlet extends HttpServlet {
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-
-        List<Policy> policies;
         String name = req.getParameter("name");
-
-        if (!name.equals("*")) {
-            StatementList statementList = new StatementList();
-            StatementElement st = new StatementElement("name", "=", name, "");
-            statementList.addStatement(st);
-            policies = dataStore.getPolicyDao().getObjects(statementList);
-            if (!policies.isEmpty()) {
-                resp.getOutputStream().write(JsonStream.serialize(policies.get(0)).getBytes());
-                resp.setStatus(200);
-            } else {
-                resp.setStatus(404); // 404 status code for Not Found
-                resp.getWriter().write("{\"message\": \"No policy found.\"}");
-            }
-        } else {
-            policies = dataStore.getPolicyDao().getObjects(null);
-            resp.getOutputStream().write(JsonStream.serialize(policies).getBytes());
-            resp.setStatus(200);
-        }
+        PolicyProfileServlet.getPolicyAndSendResponse(resp, name);
     }
 
     @Override
@@ -65,17 +41,9 @@ public class PolicyServlet extends HttpServlet {
         Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A");
         String result = s.hasNext() ? s.next() : "";
         final JSONObject obj = new JSONObject(result);
-        final String jsonString = obj.toString();
+        final String policyData = obj.toString();
 
-        StatementList update = new StatementList();
-        StatementElement st0 = new StatementElement("name", "=", name, "");
-        update.addStatement(st0);
-        StatementElement st2 = new StatementElement("policyData", "=", jsonString, "");
-        update.addStatement(st2);
-        StatementList constraint = new StatementList();
-        StatementElement st3 = new StatementElement("name", "=", name, "");
-        constraint.addStatement(st3);
-        if (dataStore.getPolicyDao().updateObject(update, constraint)) resp.setStatus(200);
+        if (dataStore.getPolicyDao().updateObject(name, policyData)) resp.setStatus(200);
         else resp.sendError(500, "could not update the group's name!");
     }
 
@@ -102,10 +70,10 @@ public class PolicyServlet extends HttpServlet {
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         String name = req.getParameter("name");
 
-        StatementElement statementElement = new StatementElement("name", "=", name, "");
-        StatementList constraint = new StatementList();
-        constraint.addStatement(statementElement);
-        if (dataStore.getPolicyDao().deleteObject(constraint)) resp.setStatus(200);
+        if (dataStore.getPolicyDao().deleteObject(name)) {
+            resp.setStatus(200);
+            return;
+        }
 
         resp.sendError(500, "Could not delete the blueprint successfully!");
     }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java
index 6a9462a31b1881d6270ea901f1555ae780195b77..ab32114b5eca71bb68a98e72c81b357fa0e0ca02 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java
@@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.UserGroupMapping;
 
@@ -22,6 +20,7 @@ import org.json.JSONObject;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 @WebServlet("/api/admin/group/members/*")
@@ -47,13 +46,7 @@ public class UserGroupServlet extends HttpServlet {
 
         String groupId = req.getPathInfo().replace("/", "");
 
-        StatementList statementList = new StatementList();
-        StatementElement st = new StatementElement("groupId", "=", groupId, "");
-
-        statementList.addStatement(st);
-
-        List<UserGroupMapping> result =
-                dataStore.getUserGroupMappingsDao().getObjects(statementList);
+        List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getByGroupId(groupId);
 
         if (result.isEmpty()) resp.sendError(404, "No users found for this group!");
         else {
@@ -77,17 +70,15 @@ public class UserGroupServlet extends HttpServlet {
 
         String username = obj.getString("username");
 
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("groupId", "=", groupId, "AND"));
-        statementList.addStatement(new StatementElement("username", "=", username, ""));
+        Optional<UserGroupMapping> existingMapping =
+                dataStore.getUserGroupMappingsDao().getByGroupIdAndUsername(groupId, username);
 
-        if (!dataStore.getUserGroupMappingsDao().getObjects(statementList).isEmpty()) {
+        if (existingMapping.isPresent()) {
             resp.sendError(409, "The user already part of the group!");
             return;
         }
 
         UserGroupMapping mapping = new UserGroupMapping();
-
         mapping.setGroupId(groupId);
         mapping.setUsername(username);
 
@@ -111,13 +102,7 @@ public class UserGroupServlet extends HttpServlet {
 
         String username = obj.getString("username");
 
-        StatementElement statementElement1 = new StatementElement("username", "=", username, "AND");
-        StatementElement statementElement2 = new StatementElement("groupId", "=", groupId, "");
-
-        StatementList constraint = new StatementList();
-        constraint.addStatement(statementElement1);
-        constraint.addStatement(statementElement2);
-        if (dataStore.getUserGroupMappingsDao().deleteObject(constraint)) {
+        if (dataStore.getUserGroupMappingsDao().deleteObject(username, groupId)) {
             resp.setStatus(200);
         } else {
             resp.sendError(500, "Could not delete mapping between user and group!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java
index 8dfbdba37f6283c98c0f3a8c0a12fae149da71f8..796e78d560f5eb2f4c07c3e53121aa81a9f2d63b 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java
@@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.UserGroupMapping;
 
@@ -45,13 +43,7 @@ public class UserGroupsServlet extends HttpServlet {
 
         String username = req.getPathInfo().replace("/", "");
 
-        StatementList statementList = new StatementList();
-        StatementElement st = new StatementElement("username", "=", username, "");
-
-        statementList.addStatement(st);
-
-        List<UserGroupMapping> result =
-                dataStore.getUserGroupMappingsDao().getObjects(statementList);
+        List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getByUsername(username);
 
         if (result.isEmpty()) resp.sendError(404, "No groups found for this user!");
         else {
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
index ee33defd64935b43326ebff7442ace41e10c0e53..0e7ab354f88edb78224595565f7bc4ba7c979ac1 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
@@ -39,8 +39,6 @@ import net.jami.jams.authmodule.PasswordUtil;
 import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.annotations.ScopedServletMethod;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.responses.DeviceRevocationResponse;
 import net.jami.jams.common.objects.user.AccessLevel;
@@ -49,11 +47,14 @@ import net.jami.jams.server.core.workflows.RevokeDeviceFlow;
 import net.jami.jams.server.core.workflows.RevokeUserFlow;
 
 import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.cert.X509CRLEntryHolder;
+import org.bouncycastle.cert.X509CRLHolder;
 import org.json.JSONObject;
 
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
@@ -64,48 +65,37 @@ public class UserServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        StatementList statementList = new StatementList();
-        StatementElement st1 =
-                new StatementElement("username", "=", req.getParameter("username"), "");
-        statementList.addStatement(st1);
-        if (!dataStore.getUserDao().getObjects(statementList).isEmpty()) {
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
-            if (certificateAuthority.getLatestCRL().get() != null)
-                user.setRevoked(
-                        certificateAuthority
-                                        .getLatestCRL()
-                                        .get()
-                                        .getRevokedCertificate(
-                                                user.getCertificate().getSerialNumber())
-                                != null);
-            else user.setRevoked(false);
-            if (!user.getNeedsPasswordReset() && req.getParameter("needPW") != null) {
-                String pw =
-                        PasswordUtil.hashPassword(
-                                req.getParameter("password"), Base64.decodeBase64(user.getSalt()));
-                StatementList update = new StatementList();
-                StatementElement st0 = new StatementElement("password", "=", pw, "");
-                update.addStatement(st0);
-                StatementList constraint = new StatementList();
-                StatementElement st =
-                        new StatementElement("username", "=", req.getParameter("username"), "");
-                constraint.addStatement(st);
-                StatementElement st2 = new StatementElement("needsPasswordReset", "=", "true", "");
-                update.addStatement(st2);
-                // refresh variable
-                dataStore.getUserDao().updateObject(update, constraint);
-                user = dataStore.getUserDao().getObjects(statementList).get(0);
-            }
-            user.setPassword("");
-            user.setSalt("");
-            resp.getOutputStream().write(JsonStream.serialize(user).getBytes());
-            resp.setStatus(200);
-        } else {
+        String username = req.getParameter("username");
+        Optional<User> result = dataStore.getUserDao().getByUsername(username);
+        if (result.isEmpty()) {
             resp.sendError(404, "Could not obtain user!");
         }
+
+        User user = result.get();
+        X509CRLHolder crl = certificateAuthority.getLatestCRL().get();
+        if (crl != null) {
+            X509CRLEntryHolder revoked =
+                    crl.getRevokedCertificate(user.getCertificate().getSerialNumber());
+            user.setRevoked(revoked != null);
+        } else {
+            user.setRevoked(false);
+        }
+
+        if (!user.getNeedsPasswordReset() && req.getParameter("needPW") != null) {
+            String pw = req.getParameter("password");
+            String password = PasswordUtil.hashPassword(pw, Base64.decodeBase64(user.getSalt()));
+            dataStore.getUserDao().updateObject(password, username);
+
+            user = dataStore.getUserDao().getByUsername(username).get();
+        }
+        user.setPassword("");
+        user.setSalt("");
+        resp.getOutputStream().write(JsonStream.serialize(user).getBytes());
+        resp.setStatus(200);
     }
-    // Create an internal user - this is always technically available, because internal users have
-    // the right to exist.
+
+    // Create an internal user - this is always technically available, because
+    // internal users have the right to exist.
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
@@ -116,29 +106,39 @@ public class UserServlet extends HttpServlet {
                         req.getReader()
                                 .lines()
                                 .collect(Collectors.joining(System.lineSeparator())));
-        String pw = obj.getString("password");
-        if (!pw.isEmpty()) {
-            User user = new User();
-            user.setUsername(obj.getString("username"));
-            user.setNeedsPasswordReset(true);
-            byte[] salt = PasswordUtil.generateSalt();
-            pw = PasswordUtil.hashPassword(pw, salt);
-            user.setPassword(pw);
-            user.setSalt(Base64.encodeBase64String(salt));
-            user.setRealm("LOCAL");
-            user.setUserType(AuthenticationSourceType.LOCAL);
-            if (userAuthenticationModule.createUser(
-                    user.getUserType(), user.getRealm(), nameServer, user)) {
-                HashMap<String, String> statusInfo = new HashMap<>();
-                statusInfo.put("password", pw);
-                resp.getOutputStream().write(JsonStream.serialize(statusInfo).getBytes());
-                resp.setStatus(200);
-                return;
-            }
+
+        String password = obj.getString("password");
+
+        if (password.isEmpty()) {
+            resp.sendError(400, "Password is empty!");
+            return;
+        }
+
+        byte[] salt = PasswordUtil.generateSalt();
+        String hashedPassword = PasswordUtil.hashPassword(password, salt);
+
+        String username = obj.getString("username");
+
+        User user = new User();
+        user.setUsername(username);
+        user.setNeedsPasswordReset(true);
+        user.setPassword(hashedPassword);
+        user.setSalt(Base64.encodeBase64String(salt));
+        user.setRealm("LOCAL");
+        user.setUserType(AuthenticationSourceType.LOCAL);
+
+        if (userAuthenticationModule.createUser(
+                user.getUserType(), user.getRealm(), nameServer, user)) {
+            HashMap<String, String> statusInfo = new HashMap<>();
+            statusInfo.put("password", hashedPassword);
+            resp.getOutputStream().write(JsonStream.serialize(statusInfo).getBytes());
+            resp.setStatus(200);
+            return;
         }
 
         resp.sendError(500, "Could not create a user successfully!");
     }
+
     // Update user data.
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
@@ -151,17 +151,17 @@ public class UserServlet extends HttpServlet {
         String pw = obj.getString("password");
         String username = obj.getString("username");
 
-        StatementList statementList = new StatementList();
-        StatementElement st0 = new StatementElement("username", "=", username, "");
-        statementList.addStatement(st0);
-        if (dataStore.getUserDao().getObjects(statementList).isEmpty()) {
+        Optional<User> result = dataStore.getUserDao().getByUsername(username);
+
+        if (result.isEmpty()) {
             resp.sendError(404, "User was not found!");
             return;
         }
 
-        User user = dataStore.getUserDao().getObjects(statementList).get(0);
+        User user = result.get();
 
-        // Check if he is AD/LDAP - then return a 403, because we can't set such password.
+        // Check if he is AD/LDAP - then return a 403, because we can't set such
+        // password.
         if (user.getUserType() != AuthenticationSourceType.LOCAL) {
             resp.sendError(
                     500, "The user is not a local user, therefore we cannot change his data!");
@@ -169,29 +169,22 @@ public class UserServlet extends HttpServlet {
         }
 
         byte[] salt = PasswordUtil.generateSalt();
-        StatementList update = new StatementList();
-        StatementElement st1 =
-                new StatementElement("password", "=", PasswordUtil.hashPassword(pw, salt), "");
-        update.addStatement(st1);
-        StatementElement st2 =
-                new StatementElement("salt", "=", Base64.encodeBase64String(salt), "");
-        update.addStatement(st2);
-        StatementList constraint = new StatementList();
-        StatementElement st3 = new StatementElement("username", "=", username, "");
-        constraint.addStatement(st3);
-        if (dataStore.getUserDao().updateObject(update, constraint)) resp.setStatus(200);
+        String password = PasswordUtil.hashPassword(pw, salt);
+        String encodedSalt = Base64.encodeBase64String(salt);
+        if (dataStore.getUserDao().updateObject(password, encodedSalt, username))
+            resp.setStatus(200);
         else resp.sendError(500, "could not update the users's data field!");
     }
+
     // Revoke a user.
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        String username = req.getParameter("username");
         AtomicReference<DeviceRevocationResponse> devResponse =
-                new AtomicReference<>(RevokeUserFlow.revokeUser(req.getParameter("username")));
-        StatementList statementList = new StatementList();
-        StatementElement st1 = new StatementElement("owner", "=", req.getParameter("username"), "");
-        statementList.addStatement(st1);
-        List<Device> devices = dataStore.getDeviceDao().getObjects(statementList);
+                new AtomicReference<>(RevokeUserFlow.revokeUser(username));
+        List<Device> devices = dataStore.getDeviceDao().getByOwner(username);
+
         if (certificateAuthority.getLatestCRL() != null) {
             devices.forEach(
                     device -> {
@@ -202,8 +195,7 @@ public class UserServlet extends HttpServlet {
                                                 device.getCertificate().getSerialNumber())
                                 == null)
                             devResponse.set(
-                                    RevokeDeviceFlow.revokeDevice(
-                                            req.getParameter("username"), device.getDeviceId()));
+                                    RevokeDeviceFlow.revokeDevice(username, device.getDeviceId()));
                     });
         }
         if (devResponse.get() != null && devResponse.get().isSuccess()) {
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java
index 6ec96c579e07c3100636c8d2bec21ecb76410872..a2f593cb3a575c9977d56f10d48219aa652c44c8 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java
@@ -46,8 +46,6 @@ public class UsersServlet extends HttpServlet {
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         resp.getOutputStream()
-                .write(
-                        JsonStream.serialize(dataStore.getUserDao().getObjects(null).get(0))
-                                .getBytes());
+                .write(JsonStream.serialize(dataStore.getUserDao().getAll().get(0)).getBytes());
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java
index 246332af817f7ad947f6e61e3a02a3aefd32bb3b..1eb9d414f3cf744889f11f38b9e31ff4bc930496 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java
@@ -33,8 +33,6 @@ import jakarta.servlet.http.HttpServlet;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.contacts.Contact;
 import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler;
 import net.jami.jams.common.utils.ContactMerger;
@@ -42,7 +40,6 @@ import net.jami.jams.common.utils.ContactMerger;
 import org.json.JSONObject;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Scanner;
@@ -64,10 +61,8 @@ public class ContactServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getAttribute("username").toString(), ""));
-        List<Contact> contactList = dataStore.getContactDao().getObjects(statementList);
+        String username = req.getAttribute("username").toString();
+        List<Contact> contactList = dataStore.getContactDao().getByOwner(username);
         resp.getOutputStream().write(JsonStream.serialize(contactList).getBytes());
     }
 
@@ -90,20 +85,21 @@ public class ContactServlet extends HttpServlet {
         Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A");
         String res = s.hasNext() ? s.next() : "";
         final JSONObject obj = new JSONObject(res);
-        Contact contact = new Contact();
+
         // TODO: Replace with mergetool.
+        Contact contact = new Contact();
         contact.setDisplayName(obj.get("displayName").toString());
         contact.setTimestamp(System.currentTimeMillis() / 1000);
         contact.setStatus('A');
         contact.setOwner(req.getAttribute("username").toString());
         contact.setUri(obj.get("uri").toString());
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getAttribute("username").toString(), ""));
-        List<Contact> localList = dataStore.getContactDao().getObjects(statementList);
-        List<Contact> remoteList = new ArrayList<>();
-        remoteList.add(contact);
+
+        String owner = req.getAttribute("username").toString();
+        List<Contact> localList = dataStore.getContactDao().getByOwner(owner);
+
+        List<Contact> remoteList = List.of(contact);
         List<Contact> result = ContactMerger.mergeContacts(localList, remoteList);
+
         if (dataStore.getContactDao().storeContactList(result)) resp.setStatus(200);
         else
             TomcatCustomErrorHandler.sendCustomError(
@@ -124,22 +120,10 @@ public class ContactServlet extends HttpServlet {
     @Override
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getAttribute("username").toString(), "AND"));
-        statementList.addStatement(new StatementElement("uri", "=", req.getParameter("uri"), ""));
-        /*
-         * List<Contact> remoteList =
-         * dataStore.getContactDao().getObjects(statementList);
-         * remoteList.get(0).setStatus('D');
-         * remoteList.get(0).setTimestamp(System.currentTimeMillis()); statementList =
-         * new StatementList(); statementList.addStatement(new
-         * StatementElement("owner","=",req.getAttribute("username").toString(),""));
-         * List<Contact> localList =
-         * dataStore.getContactDao().getObjects(statementList); List<Contact> result =
-         * ContactMerger.mergeContacts(localList,remoteList);
-         */
-        if (dataStore.getContactDao().deleteObject(statementList)) resp.setStatus(200);
+        String owner = req.getAttribute("username").toString();
+        String uri = req.getParameter("uri");
+
+        if (dataStore.getContactDao().deleteObject(owner, uri)) resp.setStatus(200);
         else
             TomcatCustomErrorHandler.sendCustomError(
                     resp, 500, "could not delete a contact due to server-side error");
@@ -162,16 +146,16 @@ public class ContactServlet extends HttpServlet {
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(
-                new StatementElement("owner", "=", req.getAttribute("username").toString(), ""));
-        List<Contact> localList = dataStore.getContactDao().getObjects(statementList);
+        String owner = req.getAttribute("username").toString();
+        List<Contact> localList = dataStore.getContactDao().getByOwner(owner);
         List<Contact> remoteList =
                 Arrays.asList(
                         JsonIterator.deserialize(
                                 req.getInputStream().readAllBytes(), Contact[].class));
-        remoteList.forEach(contact -> contact.setOwner(req.getAttribute("username").toString()));
+
+        remoteList.forEach(contact -> contact.setOwner(owner));
         List<Contact> result = ContactMerger.mergeContacts(localList, remoteList);
+
         if (!dataStore.getContactDao().storeContactList(result))
             TomcatCustomErrorHandler.sendCustomError(resp, 500, "Could not store contacts!");
         else resp.getOutputStream().write(JsonStream.serialize(result).getBytes());
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java
index f812e639344b3f0d05f2bf686384fd4510328c12..aa3031ec1569fba03b83a6eb8933493914e68f5d 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java
@@ -37,8 +37,6 @@ import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.requests.DeviceRegistrationRequest;
 import net.jami.jams.common.objects.responses.DeviceRegistrationResponse;
@@ -76,12 +74,10 @@ public class DeviceServlet extends HttpServlet {
             throws ServletException, IOException {
         String username = req.getAttribute("username").toString();
         String deviceId = req.getPathInfo().replace("/", "");
-        StatementList statementList = new StatementList();
-        StatementElement st1 = new StatementElement("owner", "=", username, "AND");
-        StatementElement st2 = new StatementElement("deviceId", "=", deviceId, "");
-        statementList.addStatement(st1);
-        statementList.addStatement(st2);
-        Device device = dataStore.getDeviceDao().getObjects(statementList).get(0);
+
+        Device device =
+                dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username).orElseThrow();
+
         if (certificateAuthority.getLatestCRL().get() != null)
             device.setRevoked(
                     certificateAuthority
@@ -123,11 +119,14 @@ public class DeviceServlet extends HttpServlet {
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.USER})
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        Gson gson = new Gson();
+        String username = req.getAttribute("username").toString();
+
         DeviceRegistrationRequest request =
                 JsonIterator.deserialize(
                         req.getInputStream().readAllBytes(), DeviceRegistrationRequest.class);
         DeviceRegistrationResponse devResponse =
-                RegisterDeviceFlow.registerDevice(req.getAttribute("username").toString(), request);
+                RegisterDeviceFlow.registerDevice(username, request);
 
         if (devResponse == null) {
             TomcatCustomErrorHandler.sendCustomError(
@@ -135,7 +134,6 @@ public class DeviceServlet extends HttpServlet {
             return;
         }
 
-        Gson gson = new Gson();
         String filteredJson = gson.toJson(devResponse);
         JsonObject obj = gson.fromJson(filteredJson, JsonObject.class);
 
@@ -204,15 +202,9 @@ public class DeviceServlet extends HttpServlet {
         String username = req.getAttribute("username").toString();
         String deviceId = req.getPathInfo().replace("/", "");
         String deviceName = req.getParameter("deviceName");
-        StatementList update = new StatementList();
-        StatementElement st0 = new StatementElement("deviceName", "=", deviceName, "");
-        update.addStatement(st0);
-        StatementList constraint = new StatementList();
-        StatementElement st1 = new StatementElement("owner", "=", username, "AND");
-        StatementElement st2 = new StatementElement("deviceId", "=", deviceId, "");
-        update.addStatement(st1);
-        update.addStatement(st2);
-        if (dataStore.getDeviceDao().updateObject(update, constraint)) resp.setStatus(200);
+
+        if (dataStore.getDeviceDao().updateObject(deviceName, username, deviceId))
+            resp.setStatus(200);
         else
             TomcatCustomErrorHandler.sendCustomError(
                     resp, 500, "could not update device information due to server-side error");
@@ -235,20 +227,20 @@ public class DeviceServlet extends HttpServlet {
             throws ServletException, IOException {
         String deviceId = req.getPathInfo().replace("/", "");
         // If the device does not belong to the user throw a 403
-        StatementList statementList = new StatementList();
-        StatementElement statementElement =
-                new StatementElement("owner", "=", req.getAttribute("username").toString(), "");
-        statementList.addStatement(statementElement);
-        if (dataStore.getDeviceDao().getObjects(statementList).stream()
+        String owner = req.getAttribute("username").toString();
+
+        long deviceIdCount =
+                dataStore.getDeviceDao().getByOwner(owner).stream()
                         .filter(device -> device.getDeviceId().equals(deviceId))
-                        .count()
-                == 0) {
+                        .count();
+
+        if (deviceIdCount == 0) {
             TomcatCustomErrorHandler.sendCustomError(
                     resp, 403, "You do not have sufficient rights to revoke this device!");
             return;
         }
-        DeviceRevocationResponse devResponse =
-                RevokeDeviceFlow.revokeDevice(req.getAttribute("username").toString(), deviceId);
+
+        DeviceRevocationResponse devResponse = RevokeDeviceFlow.revokeDevice(owner, deviceId);
         if (devResponse != null)
             resp.getOutputStream().write(JsonStream.serialize(devResponse).getBytes());
         else
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java
index e99fa20378cce9f2bbf15c92f8ca60b87d963056..e8af8c4bd29ada6bc37d8d625e19e69cab528015 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java
@@ -33,8 +33,6 @@ import jakarta.servlet.http.HttpServlet;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 
 import java.io.IOException;
@@ -64,9 +62,7 @@ public class DevicesServlet extends HttpServlet {
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         String username = req.getAttribute("username").toString();
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("owner", "=", username, ""));
-        List<Device> devices = dataStore.getDeviceDao().getObjects(statementList);
+        List<Device> devices = dataStore.getDeviceDao().getByOwner(username);
         if (certificateAuthority.getLatestCRL() != null) {
             devices.forEach(
                     device -> {
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java
index 365723c062ed6fa8bdc987150fb7ecb0e6320650..281f0d1c6045d7f52220ce2a58f5aea8e4c40086 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java
@@ -32,11 +32,11 @@ import jakarta.servlet.annotation.WebServlet;
 import jakarta.servlet.http.HttpServlet;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+
 import lombok.extern.slf4j.Slf4j;
+
 import net.jami.jams.common.authentication.AuthenticationSourceType;
 import net.jami.jams.common.authmodule.AuthModuleKey;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.objects.user.UserProfile;
 
@@ -203,11 +203,7 @@ public class DirectoryEntryServlet extends HttpServlet {
 
         String jamiId = req.getParameter("jamiId");
         if (jamiId != null) {
-            StatementList statementList = new StatementList();
-            StatementElement statementElement =
-                    new StatementElement("jamiId", "=", jamiId, null);
-            statementList.addStatement(statementElement);
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
+            User user = dataStore.getUserDao().getByJamiId(jamiId).get(0);
             List<UserProfile> userProfiles = new ArrayList<>();
             userAuthenticationModule
                     .getAuthSources()
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
index 4319ce71f1ff86163c307523caec210d534619f8..ce82b41f233ef87b9977027841cd1d0f99145ce0 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
@@ -40,14 +40,10 @@ import net.jami.jams.common.annotations.JsonContent;
 import net.jami.jams.common.authentication.AuthenticationSource;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
 import net.jami.jams.common.authmodule.AuthModuleKey;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
-import net.jami.jams.common.objects.user.Group;
 import net.jami.jams.common.objects.user.Policy;
 import net.jami.jams.common.objects.user.PolicyData;
 import net.jami.jams.common.objects.user.User;
-import net.jami.jams.common.objects.user.UserGroupMapping;
 import net.jami.jams.common.objects.user.UserProfile;
 
 import org.json.JSONObject;
@@ -71,50 +67,31 @@ public class SearchDirectoryServlet extends HttpServlet {
     // requires changes on the name server as well.
     List<UserProfile> userProfiles = new ArrayList<>();
 
-    /**
-     *
-     */
     @Override
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        String pageParam = req.getParameter("page");
         Optional<Integer> page;
-        if (req.getParameter("page") == null) page = Optional.empty();
-        else page = Optional.ofNullable(Integer.parseInt(req.getParameter("page")));
+        if (pageParam == null) page = Optional.empty();
+        else page = Optional.ofNullable(Integer.parseInt(pageParam));
 
         ConcurrentHashMap<AuthModuleKey, AuthenticationSource> authSources =
                 new ConcurrentHashMap<>(userAuthenticationModule.getAuthSources());
 
         // Check if the actual user is allowed to lookup in the directory
-        Group group = new Group();
-        StatementList statementList1 = new StatementList();
-
-        statementList1.addStatement(
-                new StatementElement("username", "=", req.getAttribute("username").toString(), ""));
-        List<UserGroupMapping> mappings =
-                dataStore.getUserGroupMappingsDao().getObjects(statementList1);
-        if (mappings != null && !mappings.isEmpty()) {
-            statementList1 = new StatementList();
-            statementList1.addStatement(
-                    new StatementElement("id", "=", mappings.get(0).getGroupId(), ""));
-            group = dataStore.getGroupDao().getObjects(statementList1).get(0);
-        }
+        String username = req.getAttribute("username").toString();
+
+        try {
+            Policy policy = dataStore.getPolicyDao().getByUsername(username).orElseThrow();
+            PolicyData policyData =
+                    JsonIterator.deserialize(policy.getPolicyData(), PolicyData.class);
 
-        if (!group.isEmpty() && group.hasBlueprint()) {
-            StatementElement st2 = new StatementElement("name", "=", group.getBlueprint(), "");
-            StatementList statementList2 = new StatementList();
-            statementList2.addStatement((st2));
-            try {
-                Policy policy = dataStore.getPolicyDao().getObjects(statementList2).get(0);
-                PolicyData policyData =
-                        JsonIterator.deserialize(policy.getPolicyData(), PolicyData.class);
-                if (!policyData.getAllowLookup()) {
-                    resp.sendError(403, "Operation not allowed!");
-                    return;
-                }
-            } catch (Exception e1) {
-                log.warn(
-                        "No policy available for user - not adding a policy component to response");
+            if (!policyData.getAllowLookup()) {
+                resp.sendError(403, "Operation not allowed!");
+                return;
             }
+        } catch (Exception e1) {
+            log.warn("No policy available for user - not adding a policy component to response");
         }
 
         if (authSources.size() > 1) {
@@ -124,51 +101,42 @@ public class SearchDirectoryServlet extends HttpServlet {
                     });
         }
 
+        String queryString = req.getParameter("queryString");
+
         authSources.forEach(
                 (k, v) -> {
-                    if (req.getParameter("queryString").equals("*"))
-                        userProfiles =
-                                v.searchUserProfiles(
-                                        req.getParameter("queryString"), "FULL_TEXT_NAME", page);
-                    else {
-                        userProfiles =
-                                v.searchUserProfiles(
-                                        req.getParameter("queryString"), "FULL_TEXT_NAME", page);
-                        if (userProfiles.isEmpty()
-                                && userProfiles.addAll(
-                                        v.searchUserProfiles(
-                                                req.getParameter("queryString"),
-                                                "LOGON_NAME",
-                                                page))) {
-                            Set<UserProfile> s =
-                                    new TreeSet<UserProfile>(
-                                            new Comparator<UserProfile>() {
-                                                @Override
-                                                public int compare(UserProfile o1, UserProfile o2) {
-                                                    if (o1.getUsername().equals(o2.getUsername()))
-                                                        return 0;
-                                                    return 1;
-                                                }
-                                            });
-                            s.addAll(userProfiles);
-                            userProfiles = new ArrayList<>(s);
-                        }
+                    if (queryString.equals("*")) {
+                        userProfiles = v.searchUserProfiles(queryString, "FULL_TEXT_NAME", page);
+                    }
+                    userProfiles = v.searchUserProfiles(queryString, "FULL_TEXT_NAME", page);
+                    if (userProfiles.isEmpty()
+                            && userProfiles.addAll(
+                                    v.searchUserProfiles(queryString, "LOGON_NAME", page))) {
+                        Set<UserProfile> s =
+                                new TreeSet<UserProfile>(
+                                        new Comparator<UserProfile>() {
+                                            @Override
+                                            public int compare(UserProfile o1, UserProfile o2) {
+                                                if (o1.getUsername().equals(o2.getUsername()))
+                                                    return 0;
+                                                return 1;
+                                            }
+                                        });
+                        s.addAll(userProfiles);
+                        userProfiles = new ArrayList<>(s);
                     }
                     userProfiles.parallelStream()
                             .forEach(
                                     profile -> {
-                                        StatementList statementList = new StatementList();
-                                        StatementElement statementElement =
-                                                new StatementElement(
-                                                        "username", "=", profile.getUsername(), "");
-                                        statementList.addStatement(statementElement);
                                         List<User> results = new ArrayList<>();
-                                        while (results.size() == 0) {
+                                        while (results.isEmpty()) {
                                             results =
                                                     dataStore
                                                             .getUserDao()
-                                                            .getObjects(statementList);
-                                            if (results.size() == 0) {
+                                                            .getByUsername(profile.getUsername())
+                                                            .map(user -> List.of(user))
+                                                            .orElseGet(() -> List.of());
+                                            if (results.isEmpty()) {
                                                 User user = new User();
                                                 user.setUsername(profile.getUsername());
                                                 user.setRealm(k.getRealm());
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java
index ff01dd9289e307c648e5705a759037a0aa09c9bf..c23770a95e81f07d15093a7ad9573fd7ea9f2ce1 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java
@@ -25,7 +25,6 @@ import jakarta.servlet.http.HttpServlet;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
-import net.jami.jams.common.objects.user.Group;
 import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler;
 import net.jami.jams.server.core.workflows.RegisterDeviceFlow;
 import net.jami.jams.server.servlets.api.auth.device.DeviceServlet;
@@ -69,8 +68,7 @@ public class PolicyDataServlet extends HttpServlet {
             throws ServletException, IOException {
         String username = req.getAttribute("username").toString();
 
-        Group group = RegisterDeviceFlow.getGroupByUsername(username);
-        String policyData = RegisterDeviceFlow.getPolicyData(group);
+        String policyData = RegisterDeviceFlow.getPolicyData(username);
 
         if (policyData == null) {
             TomcatCustomErrorHandler.sendCustomError(
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
index 4fb2a126ffd955304798c0bf795272ae655b14fe..c0e76bba33d4b456b1379f078eaa7972a96cc87e 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
@@ -35,12 +35,11 @@ import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.common.annotations.ScopedServletMethod;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
 
 import java.io.IOException;
+import java.util.Optional;
 
 @WebServlet("/api/auth/user")
 public class UserServlet extends HttpServlet {
@@ -74,24 +73,24 @@ public class UserServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.USER})
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        StatementList statementList = new StatementList();
-        StatementElement st =
-                new StatementElement("username", "=", req.getAttribute("username").toString(), "");
-        statementList.addStatement(st);
-        if (!dataStore.getUserDao().getObjects(statementList).isEmpty()) {
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
-            if (certificateAuthority.getLatestCRL().get() != null) {
-                user.setRevoked(
-                        certificateAuthority
-                                        .getLatestCRL()
-                                        .get()
-                                        .getRevokedCertificate(
-                                                user.getCertificate().getSerialNumber())
-                                != null);
-            } else user.setRevoked(false);
-            resp.setStatus(200);
-            resp.getOutputStream().write(JsonStream.serialize(user).getBytes());
-        } else resp.sendError(404, "User was not found!");
+        String username = req.getAttribute("username").toString();
+        Optional<User> result = dataStore.getUserDao().getByUsername(username);
+        if (result.isEmpty()) {
+            resp.sendError(404, "User was not found!");
+            return;
+        }
+
+        User user = result.get();
+        if (certificateAuthority.getLatestCRL().get() != null) {
+            user.setRevoked(
+                    certificateAuthority
+                                    .getLatestCRL()
+                                    .get()
+                                    .getRevokedCertificate(user.getCertificate().getSerialNumber())
+                            != null);
+        } else user.setRevoked(false);
+        resp.setStatus(200);
+        resp.getOutputStream().write(JsonStream.serialize(user).getBytes());
     }
 
     // The user can update 3 fields: password,privatekey,publickey
@@ -110,24 +109,18 @@ public class UserServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = AccessLevel.USER)
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         String username = req.getAttribute("username").toString();
+
         // Check if he is AD/LDAP - then return a 403, because we can't set such password.
-        StatementList select = new StatementList();
-        StatementElement st = new StatementElement("username", "=", username, "");
-        select.addStatement(st);
-        if (dataStore.getUserDao().getObjects(select).get(0).getUserType()
-                != AuthenticationSourceType.LOCAL) {
+        User user = dataStore.getUserDao().getByUsername(username).orElseThrow();
+        if (user.getUserType() != AuthenticationSourceType.LOCAL) {
             resp.sendError(
                     403, "The user is not a local user, therefore we cannot change his data!");
             return;
         }
-        StatementList update = new StatementList();
-        StatementElement st0 =
-                new StatementElement("password", "=", req.getParameter("password"), "");
-        update.addStatement(st0);
-        StatementList constraint = new StatementList();
-        StatementElement st1 = new StatementElement("username", "=", username, "");
-        constraint.addStatement(st1);
-        if (dataStore.getUserDao().updateObject(update, constraint)) resp.setStatus(200);
+
+        String password = req.getParameter("password");
+
+        if (dataStore.getUserDao().updateObject(password, username)) resp.setStatus(200);
         else resp.sendError(500, "could not update the users's data field!");
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
index 72b2cc1135cabdb26328e546ea401349ea60b4c7..0240bb3b33f82a26281ee39ca41066240c3a005c 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
@@ -60,11 +60,12 @@ public class StartInstallServlet extends HttpServlet {
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         // Here we must decide which page to show - login or sign-up
-        if (dataStore != null
-                && dataStore.getUserDao() != null
-                && !dataStore.getUserDao().getObjects(null).isEmpty())
-            resp.setHeader("showLogin", "true");
-        else resp.setHeader("showLogin", "false");
+        boolean showLogin =
+                dataStore != null
+                        && dataStore.getUserDao() != null
+                        && !dataStore.getUserDao().getAll().isEmpty();
+
+        resp.setHeader("showLogin", showLogin ? "true" : "false");
     }
 
     @Override
@@ -89,7 +90,7 @@ public class StartInstallServlet extends HttpServlet {
     @JsonContent
     protected void doPut(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        if (dataStore.getUserDao().getObjects(null).size() != 0) {
+        if (!dataStore.getUserDao().getAll().isEmpty()) {
             resp.sendError(
                     500,
                     "We have tried to create an administrative account where one already exists!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java
index 6fc069c75e9c58c29a19df7159e05b48a73c3a0e..d4515409fdac36802bb49d06f1e399aa0c601b39 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java
@@ -42,7 +42,8 @@ import net.jami.jams.server.Server;
 import java.io.IOException;
 
 /**
- * Since we have the @ScopedServletMethod annotation, the admin filter became absolutely useless
+ * Since we have the @ScopedServletMethod annotation, the admin filter became
+ * absolutely useless
  * as we can simply scope things.
  */
 @WebFilter(urlPatterns = {"/api/auth/*", "/api/admin/*"})
@@ -56,23 +57,25 @@ public class DApiFilter implements Filter {
         HttpServletRequest request = (HttpServletRequest) servletRequest;
         HttpServletResponse response = (HttpServletResponse) servletResponse;
         response.setContentType("application/json;charset=UTF-8");
+
         if (!Server.isInstalled.get()) {
             TomcatCustomErrorHandler.sendCustomError(
                     response, 404, "Setup has not yet been completed!");
-        } else {
-            boolean authsuccess = false;
-            boolean isLogin = false;
-            boolean isOCSPCheck = false;
+            return;
+        }
 
-            if (request.getServletPath().contains("login")) isLogin = true;
-            else if (request.getServletPath().contains("ocsp")) isOCSPCheck = true;
-            else authsuccess = doAuthCheck(request);
-            if (authsuccess || isLogin || isOCSPCheck) {
-                filterChain.doFilter(servletRequest, servletResponse);
-            } else {
-                TomcatCustomErrorHandler.sendCustomError(
-                        response, 401, "You are not authenticated!");
-            }
+        boolean authsuccess = false;
+        boolean isLogin = false;
+        boolean isOCSPCheck = false;
+
+        if (request.getServletPath().contains("login")) isLogin = true;
+        else if (request.getServletPath().contains("ocsp")) isOCSPCheck = true;
+        else authsuccess = doAuthCheck(request);
+        if (authsuccess || isLogin || isOCSPCheck) {
+            filterChain.doFilter(servletRequest, servletResponse);
+            return;
         }
+
+        TomcatCustomErrorHandler.sendCustomError(response, 401, "You are not authenticated!");
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java
index 7bdab5d79f7b8580c4be73d711aadbcb7183c201..5ba99ad955645c0ea97a5cb355130273c04596e8 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java
@@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletRequest;
 
 import lombok.extern.slf4j.Slf4j;
 
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
 
@@ -95,13 +93,12 @@ public class FilterUtils {
                 default:
                     return false;
             }
-            StatementList statementList = new StatementList();
-            StatementElement statementElement =
-                    new StatementElement("username", "=", token.getJWTClaimsSet().getSubject(), "");
-            statementList.addStatement(statementElement);
+
+            String username = token.getJWTClaimsSet().getSubject();
             log.info("Getting user from database");
-            User user = dataStore.getUserDao().getObjects(statementList).get(0);
+            User user = dataStore.getUserDao().getByUsername(username).orElseThrow();
             log.info("User retrieved from database: {}", user);
+
             if (!user.getAccessLevelName().equals("ADMIN")
                     && certificateAuthority.getLatestCRL().get() != null) {
                 if (certificateAuthority
@@ -110,10 +107,12 @@ public class FilterUtils {
                                 .getRevokedCertificate(user.getCertificate().getSerialNumber())
                         != null) return false;
             }
+
             JWSVerifier jwsVerifier =
                     new RSASSAVerifier(userAuthenticationModule.getAuthModulePubKey());
+
             if (token.verify(jwsVerifier) && verifyValidity(token)) {
-                request.setAttribute(USERNAME_ATTR, token.getJWTClaimsSet().getSubject());
+                request.setAttribute(USERNAME_ATTR, username);
                 request.setAttribute(
                         ACCESS_LEVEL_ATTR,
                         AccessLevel.valueOf(token.getJWTClaimsSet().getClaim("scope").toString()));
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java
index 165864a3810c6062c2453cb58d404126a4220d65..819d04ac9758f2f84b645ebfd56464f888df5e3c 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java
@@ -30,8 +30,6 @@ import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
 import net.jami.jams.ca.JamsCA;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.user.User;
 
@@ -63,8 +61,10 @@ public class OCSPServlet extends HttpServlet {
             String issuerId = req.getPathInfo().replace("/", "");
 
             /*
-             * If there is no issue id we are dealing with a certificate signed byt the CA root
-             * Else the certificate is a device certificate signed by a user with and the issuerId is his Jami Id
+             * If there is no issue id we are dealing with a certificate signed byt the CA
+             * root
+             * Else the certificate is a device certificate signed by a user with and the
+             * issuerId is his Jami Id
              */
 
             if (issuerId == "") {
@@ -79,56 +79,32 @@ public class OCSPServlet extends HttpServlet {
                     byte[] respBytes = response.getEncoded();
                     resp.getOutputStream().write(respBytes);
                 } else resp.setStatus(404);
-            } else {
-                User targetUser = null;
-                StatementList userStatementsList = new StatementList();
-                StatementElement usernameStatement =
-                        new StatementElement("jamiId", "=", issuerId, "");
-                userStatementsList.addStatement(usernameStatement);
-
-                try {
-                    targetUser = dataStore.getUserDao().getObjects(userStatementsList).get(0);
-                    StatementList deviceStatementsList = new StatementList();
-                    StatementElement deviceOwnerStatement =
-                            new StatementElement("owner", "=", targetUser.getUsername(), "");
-                    deviceStatementsList.addStatement(deviceOwnerStatement);
-                    List<Device> devices =
-                            dataStore.getDeviceDao().getObjects(deviceStatementsList);
-
-                    boolean deviceDoesNotExist = true;
-                    for (Device d : devices) {
-                        for (BigInteger id : ids) {
-                            if (d.getCertificate().getSerialNumber().equals(id)) {
-                                deviceDoesNotExist = false;
-                            }
-                        }
-                    }
-                    OCSPResp response = null;
-
-                    if (deviceDoesNotExist) {
-                        response =
-                                JamsCA.getOCSPResponse(
-                                        ocspReq,
-                                        targetUser.getCertificate(),
-                                        targetUser.getPrivateKey(),
-                                        true);
-                    } else {
-                        response =
-                                JamsCA.getOCSPResponse(
-                                        ocspReq,
-                                        targetUser.getCertificate(),
-                                        targetUser.getPrivateKey(),
-                                        false);
-                    }
 
-                    if (response != null) {
-                        byte[] respBytes = response.getEncoded();
-                        resp.getOutputStream().write(respBytes);
-                    } else resp.setStatus(404);
-                } catch (Exception e) {
-                    resp.sendError(404, "Could not find the requested certificate!");
+                return;
+            }
+
+            User targetUser = dataStore.getUserDao().getByJamiId(issuerId).get(0);
+            List<Device> devices = dataStore.getDeviceDao().getByOwner(targetUser.getUsername());
+
+            boolean deviceDoesNotExist = true;
+            for (Device d : devices) {
+                for (BigInteger id : ids) {
+                    if (d.getCertificate().getSerialNumber().equals(id)) {
+                        deviceDoesNotExist = false;
+                    }
                 }
             }
+            OCSPResp response =
+                    JamsCA.getOCSPResponse(
+                            ocspReq,
+                            targetUser.getCertificate(),
+                            targetUser.getPrivateKey(),
+                            deviceDoesNotExist);
+
+            if (response != null) {
+                byte[] respBytes = response.getEncoded();
+                resp.getOutputStream().write(respBytes);
+            } else resp.setStatus(404);
 
         } catch (Exception e) {
             resp.sendError(404, "Could not find the requested certificate!");
diff --git a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
index 465d71617c61ee95251dd8690cef41003c9ad60a..a34d7ed958ea4496b3159a59bab40bc2d84442a0 100644
--- a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
+++ b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
@@ -26,12 +26,10 @@ import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.system.SystemAccount;
 import net.jami.jams.common.utils.LibraryLoader;
 
-import java.util.List;
+import java.util.Optional;
 
 @Slf4j
 public class CryptoEngineLoader {
@@ -42,22 +40,17 @@ public class CryptoEngineLoader {
             Class<?> cls = LibraryLoader.classLoader.loadClass("net.jami.jams.ca.JamsCA");
             CertificateAuthority certificateAuthority =
                     (CertificateAuthority) cls.getConstructor().newInstance();
-            StatementList statementList = new StatementList();
-            statementList.addStatement(new StatementElement("entity", "=", "CA", ""));
-            List<SystemAccount> accounts = dataStore.getSystemDao().getObjects(statementList);
-            if (accounts.size() == 0) {
+
+            Optional<SystemAccount> accounts = dataStore.getSystemDao().getCA();
+
+            if (accounts.isEmpty()) {
                 log.info(
                         "This is an fresh install, and it has no CA or any system accounts - if there is a config.json"
                                 + " file in your directory, this means the install is broken and you should delete and restart!");
             } else {
-                statementList = new StatementList();
-                statementList.addStatement(new StatementElement("entity", "=", "CA", ""));
-                SystemAccount caAccount = dataStore.getSystemDao().getObjects(statementList).get(0);
-                statementList = new StatementList();
-                statementList.addStatement(new StatementElement("entity", "=", "OCSP", ""));
-                SystemAccount ocspAccount =
-                        dataStore.getSystemDao().getObjects(statementList).get(0);
-                log.info("Injecting OCSP and CA acocunts...");
+                SystemAccount caAccount = accounts.orElseThrow();
+                SystemAccount ocspAccount = dataStore.getSystemDao().getOCSP().orElseThrow();
+                log.info("Injecting OCSP and CA accounts...");
                 certificateAuthority.init(config, caAccount, ocspAccount);
             }
             log.info(
diff --git a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
index 84e023f30a3cb7f5693d3391772c37fe2db7a41e..56c177fa8b5eb24028b8aa12a7b0af6cfd24983b 100644
--- a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
+++ b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
@@ -27,8 +27,6 @@ import static net.jami.jams.server.Server.dataStore;
 import lombok.extern.slf4j.Slf4j;
 
 import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.UserProfile;
 import net.jami.jams.ldap.connector.LDAPConnector;
 
@@ -91,13 +89,7 @@ public class UserProfileService {
                                 .map(UserProfileService::profileFromResponse)
                                 .collect(Collectors.toList());
                 for (UserProfile p : profilesFromResponse) {
-                    StatementList statementList = new StatementList();
-                    StatementElement st =
-                            new StatementElement("username", "=", p.getUsername(), "");
-                    statementList.addStatement(st);
-
-                    if (dataStore.getUserProfileDao().getObjects(statementList).isEmpty())
-                        dataStore.getUserProfileDao().storeObject(p);
+                    dataStore.getUserProfileDao().insertIfNotExists(p);
                 }
 
                 return profilesFromResponse;
diff --git a/pom.xml b/pom.xml
index f1d899b03cee7bef2a103717c6a2f1b53d6b4797..5aaff754c2b830478fb72fdecd827828e952e3d1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,6 +149,12 @@
                             </includes>
                             <followSymlinks>false</followSymlinks>
                         </fileset>
+                        <fileset>
+                            <directory>coverage/</directory>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                        </fileset>
                     </filesets>
                 </configuration>
             </plugin>