diff --git a/README.md b/README.md
index ea6024c3a918fce2eed5ad454bbcabedf002cb50..7803f6c3c3ad5a2eda567505d49ab17387ccbb86 100644
--- a/README.md
+++ b/README.md
@@ -119,6 +119,12 @@ Create the logs directory and assign ownership to the Apache user (usually www-d
     mkdir logs
     sudo chown www-data logs
 
+### Docker
+
+Database image:
+
+    docker build -f docker/db-Dockerfile --tag rap-ia2/database .
+
 ### Run Unit Tests and build code coverage report
 
 (XDebug or another code coverage driver needs to be installed; e.g. `sudo apt install php-xdebug`)
diff --git a/classes/datalayer/mysql/MySQLUserDAO.php b/classes/datalayer/mysql/MySQLUserDAO.php
index f16ce49582384050e963d9f19c3f404b9f54d6af..37f4fcd68b40e8377c941e8f6dbd5927542bf994 100644
--- a/classes/datalayer/mysql/MySQLUserDAO.php
+++ b/classes/datalayer/mysql/MySQLUserDAO.php
@@ -251,16 +251,29 @@ class MySQLUserDAO extends BaseMySQLDAO implements UserDAO {
         try {
             $dbh->beginTransaction();
 
-            // Moving identities from user2 to user1
-            $stmt1 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2");
+            // Deleting keep_separated pairs
+            $stmt1 = $dbh->prepare("DELETE FROM keep_separated WHERE "
+                    . "(user_id1 = :id1 AND user_id2 = :id2) OR"
+                    . "(user_id1 = :id2 AND user_id2 = :id1)");
             $stmt1->bindParam(':id1', $userId1);
             $stmt1->bindParam(':id2', $userId2);
             $stmt1->execute();
-
-            // Deleting user2
-            $stmt2 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2");
+            
+            // Deleting keep_separated records of user that is going to be deleted
+            $stmt2 = $dbh->prepare("DELETE FROM keep_separated WHERE user_id1 = :id2 OR user_id2 = :id2");
             $stmt2->bindParam(':id2', $userId2);
             $stmt2->execute();
+            
+            // Moving identities from user2 to user1
+            $stmt3 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2");
+            $stmt3->bindParam(':id1', $userId1);
+            $stmt3->bindParam(':id2', $userId2);
+            $stmt3->execute();
+
+            // Deleting user2
+            $stmt4 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2");
+            $stmt4->bindParam(':id2', $userId2);
+            $stmt4->execute();
 
             $dbh->commit();
         } catch (Exception $ex) {
diff --git a/docker/db-Dockerfile b/docker/db-Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..4ac0f9f8b02d55aa6d01115626722b7e714a2a77
--- /dev/null
+++ b/docker/db-Dockerfile
@@ -0,0 +1,7 @@
+FROM mariadb:10.5
+
+ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
+ENV MYSQL_DATABASE rap
+
+COPY sql/setup-database.sql /docker-entrypoint-initdb.d/01-setup-database.sql
+COPY sql/delete-user-procedure.sql /docker-entrypoint-initdb.d/02-delete-user-procedure.sql
diff --git a/tests/BaseDAOTest.php b/tests/BaseDAOTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c6e77e8d401ae847ef6edcfee42f6378babeb77
--- /dev/null
+++ b/tests/BaseDAOTest.php
@@ -0,0 +1,24 @@
+<?php
+
+abstract class BaseDAOTest extends \PHPUnit\Framework\TestCase {
+
+    protected function getFakeLocator(): \RAP\Locator {
+
+        $config = (object) [
+                    "databaseConfig" => (object) [
+                        "dbtype" => 'MySQL',
+                        "hostname" => "127.0.0.1",
+                        "port" => 3307,
+                        "username" => "root",
+                        "password" => "",
+                        "dbname" => "rap"
+                    ]
+        ];
+
+        $locatorStub = $this->createMock(\RAP\Locator::class);
+        $locatorStub->config = $config;
+
+        return $locatorStub;
+    }
+
+}
diff --git a/tests/MySQLUserDAOTest.php b/tests/MySQLUserDAOTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ee5b1fde162f92af57c9f8d193345341000deb1
--- /dev/null
+++ b/tests/MySQLUserDAOTest.php
@@ -0,0 +1,55 @@
+<?php
+
+class MySQLUserDAOTest extends BaseDAOTest {
+
+    public function setUp(): void {
+        $this->dao = new \RAP\MySQLUserDAO($this->getFakeLocator());
+    }
+
+    public function testJoinUsersAfterKeepSeparated() {
+
+        $user1 = $this->createUser(\RAP\Identity::EDU_GAIN, 'name.surname@inaf.it', '001');
+        $user2 = $this->createUser(\RAP\Identity::GOOGLE, 'name.surname@inaf.it', '002');
+        $user3 = $this->createUser(\RAP\Identity::LINKEDIN, 'test@inaf.it', '003');
+
+        $joinable1 = $this->dao->findJoinableUsersByUserId($user1->id);
+        $this->assertEquals(1, count($joinable1));
+        $this->assertEquals($user2->id, $joinable1[0]);
+
+        $joinable2 = $this->dao->findJoinableUsersByUserId($user2->id);
+        $this->assertEquals(1, count($joinable2));
+        $this->assertEquals($user1->id, $joinable2[0]);
+
+        // Add records to keep_separated table to test the two DELETE statements before the join
+        $this->dao->insertRejectedJoin($user1->id, $user2->id);
+        $this->dao->insertRejectedJoin($user2->id, $user3->id);
+
+        $joinable = $this->dao->findJoinableUsersByUserId($user1->id);
+        $this->assertEquals(0, count($joinable));
+
+        $this->dao->joinUsers($user1->id, $user2->id);
+
+        $joinedUser = $this->dao->findUserById($user1->id);
+        $this->assertEquals(2, count($joinedUser->identities));
+
+        $this->assertNull($this->dao->findUserById($user2->id));
+    }
+
+    private function createUser(string $identityType, string $email, string $typedId) {
+        $user = new \RAP\User();
+        $user->id = $this->dao->createUser();
+
+        $identity = new \RAP\Identity($identityType);
+        $identity->email = $email;
+        $identity->typedId = $typedId;
+
+        $this->dao->insertIdentity($identity, $user->id);
+
+        $savedUser = $this->dao->findUserById($user->id);
+
+        $this->assertEquals($user->id, $savedUser->id);
+
+        return $savedUser;
+    }
+
+}
diff --git a/views/confirm-join.php b/views/confirm-join.php
index efab33def694af4a06b41c2287868792d1920843..ee4943c42891dea45ed2d533c9d656b112a4144f 100644
--- a/views/confirm-join.php
+++ b/views/confirm-join.php
@@ -23,7 +23,7 @@ include 'include/header.php';
 
 <div class="row">
     <div class="col-xs-12 col-md-6">
-        <h4>User id: <?php echo $user->id; ?></h4>
+        <h4><?php echo $user->id === null ? '&nbsp;' : ('User id: ' . $user->id); ?></h4>
         <div class="panel">
             <div class="panel-body">
                 <?php