diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b65bafc9f260dabecd592fea4f08829f08db7c4..9948b8cdabdbb58f7a365b50e0ba88173560d5e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+* `Entity/names` resource for retrieving all known entity names.
 - Scripting is simplified by adding a `home` directory, of which a copy is
   created for each called script and set as the `HOME` environment variable.
 - [bend_symlinks.sh](misc/bend_symlinks/bend_symlinks.sh) (version 0.1, experimental)
diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md
new file mode 100644
index 0000000000000000000000000000000000000000..234ff24f40e9c281bfeb23703864c39369aaea05
--- /dev/null
+++ b/RELEASE_GUIDELINES.md
@@ -0,0 +1,27 @@
+# Release Guidelines for the CaosDB MySQL Backend
+
+This document specifies release guidelines in addition to the generel release
+guidelines of the CaosDB Project
+([RELEASE_GUIDELINES.md](https://gitlab.com/caosdb/caosdb/blob/dev/RELEASE_GUIDELINES.md))
+
+## General Prerequisites
+
+* All tests are passing.
+* FEATURES.md is up-to-date and a public API is being declared in that document.
+* CHANGELOG.md is up-to-date.
+* DEPENDENCIES.md is up-to-date.
+
+## Steps
+
+1. Create a release branch from the dev branch. This prevents further changes
+   to the code base and a never ending release process. Naming: `release-<VERSION>`
+
+2. Check all general prerequisites.
+
+4. Merge the release branch into the master branch.
+
+5. Tag the latest commit of the master branch with `v<VERSION>`.
+
+6. Delete the release branch.
+
+7. Merge the master branch back into the dev branch.
diff --git a/caosdb-webui b/caosdb-webui
index 7d67a76f1ceede440a2d4dad4db8dcbd0d61b9ed..9975365e07e601efc55903e6f75a41ef63902fce 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit 7d67a76f1ceede440a2d4dad4db8dcbd0d61b9ed
+Subproject commit 9975365e07e601efc55903e6f75a41ef63902fce
diff --git a/makefile b/makefile
index 49c65fbf7cd92e2100bd41d337464ee8e9033a3d..98825d4baeb85f497d9825d651f2afbad1e92f7d 100644
--- a/makefile
+++ b/makefile
@@ -38,6 +38,9 @@ run: compile
 run-debug: jar
 	java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar
 
+run-debug-single:
+	java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar
+
 run-single:
 	java -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar
 
diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/caosdb/server/CaosDBServer.java
index b725ab73e87d34345cf7bba2be605033561efef9..34bfe3e2911955fa724ea5e6ac7258d80f9cc120 100644
--- a/src/main/java/caosdb/server/CaosDBServer.java
+++ b/src/main/java/caosdb/server/CaosDBServer.java
@@ -54,6 +54,7 @@ import caosdb.server.resource.UserResource;
 import caosdb.server.resource.UserRolesResource;
 import caosdb.server.resource.Webinterface;
 import caosdb.server.resource.WebinterfaceBuildNumber;
+import caosdb.server.resource.transaction.EntityNamesResource;
 import caosdb.server.resource.transaction.EntityResource;
 import caosdb.server.terminal.CaosDBTerminal;
 import caosdb.server.terminal.StatsPanel;
@@ -632,6 +633,8 @@ public class CaosDBServer extends Application {
     authenticator.setNext(authorizer);
 
     protectedRouter.attach("/scripting", ScriptingResource.class);
+    protectedRouter.attach("/Entities/names", EntityNamesResource.class);
+    protectedRouter.attach("/Entity/names", EntityNamesResource.class);
     protectedRouter.attach("/Entities", EntityResource.class);
     protectedRouter.attach("/Entities/", EntityResource.class);
     protectedRouter.attach("/Entities/{specifier}", EntityResource.class);
diff --git a/src/main/java/caosdb/server/database/BackendTransaction.java b/src/main/java/caosdb/server/database/BackendTransaction.java
index 896491bfba98390fb4c9fdf7ddde4c0ee56e3f6a..14e65e86bd9fe05b074c731e27b601fa4ed51f68 100644
--- a/src/main/java/caosdb/server/database/BackendTransaction.java
+++ b/src/main/java/caosdb/server/database/BackendTransaction.java
@@ -28,6 +28,7 @@ import caosdb.server.database.backend.implementation.MySQL.MySQLDeletePassword;
 import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteRole;
 import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteSparseEntity;
 import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteUser;
+import caosdb.server.database.backend.implementation.MySQL.MySQLGetAllNames;
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetChildren;
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetDependentEntities;
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetFileRecordByPath;
@@ -81,6 +82,7 @@ import caosdb.server.database.backend.interfaces.FileCheckHash;
 import caosdb.server.database.backend.interfaces.FileCheckSize;
 import caosdb.server.database.backend.interfaces.FileExists;
 import caosdb.server.database.backend.interfaces.FileWasModifiedAfter;
+import caosdb.server.database.backend.interfaces.GetAllNamesImpl;
 import caosdb.server.database.backend.interfaces.GetChildrenImpl;
 import caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl;
 import caosdb.server.database.backend.interfaces.GetFileIteratorImpl;
@@ -144,8 +146,15 @@ public abstract class BackendTransaction implements Undoable {
     this.addMeasurement(this, t2 - t1);
   }
 
+  /**
+   * Intialiaze the adapters to the database backend.
+   *
+   * <p>Currently this is hard-coded to the MySQL-Backend but the architecture of this class is
+   * designed to make it easy in the future to choose other implementations (i.e. other back-ends)
+   */
   public static void init() {
     if (impl.isEmpty()) {
+      setImpl(GetAllNamesImpl.class, MySQLGetAllNames.class);
       setImpl(DeleteEntityPropertiesImpl.class, MySQLDeleteEntityProperties.class);
       setImpl(DeleteSparseEntityImpl.class, MySQLDeleteSparseEntity.class);
       setImpl(GetChildrenImpl.class, MySQLGetChildren.class);
diff --git a/src/main/java/caosdb/server/database/DatabaseUtils.java b/src/main/java/caosdb/server/database/DatabaseUtils.java
index 7c50f47a01a8528cd078b87eebbe9495d6ebaaa4..84c38fa448b7d8a1035aa28ded7bbfcecc5a88b3 100644
--- a/src/main/java/caosdb/server/database/DatabaseUtils.java
+++ b/src/main/java/caosdb/server/database/DatabaseUtils.java
@@ -186,26 +186,44 @@ public class DatabaseUtils {
     return ret;
   }
 
+  /**
+   * Helper function for parsing MySQL results.
+   *
+   * <p>This function creates SparseEntities and parses only the name, the role and the acl of an
+   * entity.
+   *
+   * <p>Never returns null.
+   */
+  public static SparseEntity parseNameRoleACL(ResultSet rs) throws SQLException {
+    final SparseEntity ret = new SparseEntity();
+    ret.role = bytes2UTF8(rs.getBytes("EntityRole"));
+    ret.name = bytes2UTF8(rs.getBytes("EntityName"));
+    ret.acl = bytes2UTF8(rs.getBytes("ACL"));
+    return ret;
+  }
+
+  /**
+   * Helper function for parsing MySQL results.
+   *
+   * <p>This function creates SparseEntities and parses all fields which belong to a SparseEntity:
+   * id, name, role, acl, description, datatype, and the file properties.
+   *
+   * <p>Never returns null.
+   */
   public static SparseEntity parseEntityResultSet(final ResultSet rs) throws SQLException {
-    if (rs.next()) {
-      final SparseEntity ret = new SparseEntity();
-      ret.id = rs.getInt("EntityID");
-      ret.name = bytes2UTF8(rs.getBytes("EntityName"));
-      ret.description = bytes2UTF8(rs.getBytes("EntityDesc"));
-      ret.role = bytes2UTF8(rs.getBytes("EntityRole"));
-      ret.datatype = bytes2UTF8(rs.getBytes("Datatype"));
-      ret.collection = bytes2UTF8(rs.getBytes("Collection"));
-      ret.acl = bytes2UTF8(rs.getBytes("ACL"));
+    SparseEntity ret = parseNameRoleACL(rs);
+    ret.id = rs.getInt("EntityID");
+    ret.description = bytes2UTF8(rs.getBytes("EntityDesc"));
+    ret.datatype = bytes2UTF8(rs.getBytes("Datatype"));
+    ret.collection = bytes2UTF8(rs.getBytes("Collection"));
 
-      final String path = bytes2UTF8(rs.getBytes("FilePath"));
-      if (!rs.wasNull()) {
-        ret.filePath = path;
-        ret.fileSize = rs.getLong("FileSize");
-        ret.fileHash = bytes2UTF8(rs.getBytes("FileHash"));
-      }
-      return ret;
+    final String path = bytes2UTF8(rs.getBytes("FilePath"));
+    if (!rs.wasNull()) {
+      ret.filePath = path;
+      ret.fileSize = rs.getLong("FileSize");
+      ret.fileHash = bytes2UTF8(rs.getBytes("FileHash"));
     }
-    return null;
+    return ret;
   }
 
   public static ArrayList<VerySparseEntity> parseParentResultSet(final ResultSet rs)
diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7c641cadebcde93b97187aa7a0ea2ded72d4678
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java
@@ -0,0 +1,46 @@
+package caosdb.server.database.backend.implementation.MySQL;
+
+import caosdb.server.database.DatabaseUtils;
+import caosdb.server.database.access.Access;
+import caosdb.server.database.backend.interfaces.GetAllNamesImpl;
+import caosdb.server.database.exceptions.TransactionException;
+import caosdb.server.database.proto.SparseEntity;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Retrieve name, role and acl of all entities from the MySQL backend. */
+public class MySQLGetAllNames extends MySQLTransaction implements GetAllNamesImpl {
+
+  public MySQLGetAllNames(Access access) {
+    super(access);
+  }
+
+  public static final String STMT_GET_ALL_NAMES =
+      "Select e.name as EntityName, e.role as EntityRole, a.acl as ACL FROM entities as e JOIN entity_acl as a ON (a.id=e.acl) WHERE e.name IS NOT NULL and e.role!='ROLE'";
+
+  @Override
+  public List<SparseEntity> execute() {
+    ArrayList<SparseEntity> ret = new ArrayList<>();
+
+    try {
+      PreparedStatement stmt = prepareStatement(STMT_GET_ALL_NAMES);
+
+      try (ResultSet resultSet = stmt.executeQuery()) {
+        while (resultSet.next()) {
+          SparseEntity spe = DatabaseUtils.parseNameRoleACL(resultSet);
+          ret.add(spe);
+        }
+
+      } catch (SQLException e1) {
+        throw new TransactionException(e1);
+      }
+    } catch (SQLException | ConnectionException e2) {
+      throw new TransactionException(e2);
+    }
+
+    return ret;
+  }
+}
diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
index 30a07213186703596e1afeae6d4c62b1cd0602be..749b0b91455c9f429821bbabce3aa99375a417cd 100644
--- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
+++ b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
@@ -31,6 +31,11 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
+/**
+ * Retrieve a single SparseEntity by id.
+ *
+ * <p>A SparseEntity contains only id, name, role, acl, datatype and the file properties.
+ */
 public class MySQLRetrieveSparseEntity extends MySQLTransaction
     implements RetrieveSparseEntityImpl {
 
@@ -48,7 +53,9 @@ public class MySQLRetrieveSparseEntity extends MySQLTransaction
       preparedStatement.setInt(1, id);
       final ResultSet rs = preparedStatement.executeQuery();
       try {
-        return DatabaseUtils.parseEntityResultSet(rs);
+        if (rs.next()) {
+          return DatabaseUtils.parseEntityResultSet(rs);
+        }
       } finally {
         rs.close();
       }
@@ -57,5 +64,6 @@ public class MySQLRetrieveSparseEntity extends MySQLTransaction
     } catch (final ConnectionException e) {
       throw new TransactionException(e);
     }
+    return null;
   }
 }
diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java b/src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a89e579d2713457c72ec2df73e1c1c936d50db2
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java
@@ -0,0 +1,14 @@
+package caosdb.server.database.backend.interfaces;
+
+import caosdb.server.database.proto.SparseEntity;
+import java.util.List;
+
+/**
+ * Interface for the retrieval of all known names from the backend.
+ *
+ * <p>The returned list contains SparseEntities which have only their name, role and acl defined.
+ */
+public interface GetAllNamesImpl extends BackendTransactionImpl {
+
+  List<SparseEntity> execute();
+}
diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java b/src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java
new file mode 100644
index 0000000000000000000000000000000000000000..f30ec5b2b33de6ba7341b26f4e94244f6501255c
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java
@@ -0,0 +1,29 @@
+package caosdb.server.database.backend.transaction;
+
+import caosdb.server.database.BackendTransaction;
+import caosdb.server.database.backend.interfaces.GetAllNamesImpl;
+import caosdb.server.database.proto.SparseEntity;
+import caosdb.server.entity.Entity;
+import caosdb.server.entity.EntityInterface;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GetAllNames extends BackendTransaction {
+
+  private List<SparseEntity> entities;
+
+  @Override
+  protected void execute() {
+    final GetAllNamesImpl t = getImplementation(GetAllNamesImpl.class);
+
+    this.entities = t.execute();
+  }
+
+  public List<EntityInterface> getEntities() {
+    ArrayList<EntityInterface> ret = new ArrayList<>();
+    for (SparseEntity e : entities) {
+      ret.add(new Entity().parseSparseEntity(e));
+    }
+    return ret;
+  }
+}
diff --git a/src/main/java/caosdb/server/entity/Entity.java b/src/main/java/caosdb/server/entity/Entity.java
index bf1022dad1c0e6b954ea876ecce674a87ff7650e..19cd930706e3f3aa691853b020f000191ed8d142 100644
--- a/src/main/java/caosdb/server/entity/Entity.java
+++ b/src/main/java/caosdb/server/entity/Entity.java
@@ -100,7 +100,7 @@ public class Entity extends AbstractObservable implements EntityInterface {
   @Override
   public void checkPermission(final Subject subject, final Permission permission) {
     try {
-      if (!this.entityACL.isPermitted(subject, permission)) {
+      if (!this.hasPermission(subject, permission)) {
         throw new AuthorizationException(
             subject.getPrincipal().toString()
                 + " doesn't have permission "
@@ -117,6 +117,17 @@ public class Entity extends AbstractObservable implements EntityInterface {
     checkPermission(subject, permission);
   }
 
+  @Override
+  public boolean hasPermission(Permission permission) {
+    final Subject subject = SecurityUtils.getSubject();
+    return hasPermission(subject, permission);
+  }
+
+  @Override
+  public boolean hasPermission(Subject subject, Permission permission) {
+    return this.entityACL.isPermitted(subject, permission);
+  }
+
   @Override
   public final boolean hasProperties() {
     return !this.properties.isEmpty();
diff --git a/src/main/java/caosdb/server/entity/EntityInterface.java b/src/main/java/caosdb/server/entity/EntityInterface.java
index 76c6c51eaabb3ee5864d9cb538f43338e96ce914..21ed5cd85234bd633914302ce2982b2b6f4f9a66 100644
--- a/src/main/java/caosdb/server/entity/EntityInterface.java
+++ b/src/main/java/caosdb/server/entity/EntityInterface.java
@@ -171,6 +171,12 @@ public interface EntityInterface
 
   public abstract void checkPermission(Permission permission);
 
+  /** Return true iff the current thread's subject has a permission. */
+  public abstract boolean hasPermission(Permission permission);
+
+  /** Return true iff the given subject has a permission. */
+  public abstract boolean hasPermission(Subject subject, Permission permission);
+
   public abstract boolean hasEntityACL();
 
   public abstract String getQueryTemplateDefinition();
diff --git a/src/main/java/caosdb/server/entity/container/TransactionContainer.java b/src/main/java/caosdb/server/entity/container/TransactionContainer.java
index 8c820a93164fd84ee6c27ea422941111ea24fdbb..f0ac55fae7b57d24456728508baa7768b83a5711 100644
--- a/src/main/java/caosdb/server/entity/container/TransactionContainer.java
+++ b/src/main/java/caosdb/server/entity/container/TransactionContainer.java
@@ -24,7 +24,6 @@ package caosdb.server.entity.container;
 
 import caosdb.server.CaosDBServer;
 import caosdb.server.database.misc.TransactionBenchmark;
-import caosdb.server.entity.Entity;
 import caosdb.server.entity.EntityInterface;
 import caosdb.server.entity.FileProperties;
 import caosdb.server.entity.xml.ToElementable;
@@ -36,7 +35,8 @@ import java.util.List;
 import org.apache.shiro.subject.Subject;
 import org.jdom2.Element;
 
-public class TransactionContainer extends Container<Entity> implements ToElementable, JobTarget {
+public class TransactionContainer extends Container<EntityInterface>
+    implements ToElementable, JobTarget {
 
   private EntityStatus status = EntityStatus.QUALIFIED;
   private final Subject owner;
diff --git a/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java b/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java
index 1feeafdb7c158edd35a2eddd16af85b40e35211c..4d419bbfc17aee5749db70976f1a510ae468032b 100644
--- a/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java
+++ b/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java
@@ -541,4 +541,14 @@ public class EntityWrapper implements EntityInterface {
   public boolean skipJob() {
     return this.entity.skipJob();
   }
+
+  @Override
+  public boolean hasPermission(Permission permission) {
+    return this.entity.hasPermission(permission);
+  }
+
+  @Override
+  public boolean hasPermission(Subject subject, Permission permission) {
+    return this.entity.hasPermission(subject, permission);
+  }
 }
diff --git a/src/main/java/caosdb/server/jobs/core/ResolveNames.java b/src/main/java/caosdb/server/jobs/core/ResolveNames.java
index f5e1695f34c30a78f136950f7aae3ae00be170e4..a7781fb4c1fd82d8a1f14df01da152b50ce86ae3 100644
--- a/src/main/java/caosdb/server/jobs/core/ResolveNames.java
+++ b/src/main/java/caosdb/server/jobs/core/ResolveNames.java
@@ -25,6 +25,7 @@ package caosdb.server.jobs.core;
 import caosdb.server.database.backend.transaction.GetIDByName;
 import caosdb.server.database.exceptions.EntityDoesNotExistException;
 import caosdb.server.entity.Entity;
+import caosdb.server.entity.EntityInterface;
 import caosdb.server.entity.container.TransactionContainer;
 import caosdb.server.jobs.ContainerJob;
 import caosdb.server.utils.EntityStatus;
@@ -41,7 +42,7 @@ public class ResolveNames extends ContainerJob {
 
   public void resolve(final TransactionContainer container) {
     final ArrayList<Entity> add = new ArrayList<Entity>();
-    for (final Entity e : container) {
+    for (final EntityInterface e : container) {
       if (e.hasName() && !e.hasId()) {
         try {
           final List<Integer> c = execute(new GetIDByName(e.getName(), false)).getList();
diff --git a/src/main/java/caosdb/server/jobs/core/RetriveAllNames.java b/src/main/java/caosdb/server/jobs/core/RetriveAllNames.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7f58e00c602d5ed9a79d9e03fa08d9941e64217
--- /dev/null
+++ b/src/main/java/caosdb/server/jobs/core/RetriveAllNames.java
@@ -0,0 +1,32 @@
+package caosdb.server.jobs.core;
+
+import caosdb.server.database.backend.transaction.GetAllNames;
+import caosdb.server.entity.EntityInterface;
+import caosdb.server.jobs.FlagJob;
+import caosdb.server.jobs.JobAnnotation;
+import caosdb.server.jobs.JobExecutionTime;
+import caosdb.server.permissions.EntityPermission;
+import caosdb.server.utils.EntityStatus;
+
+/**
+ * A jobs which retrieves all known names for which the requesting user has the RETRIEVE_ENTITY
+ * permission.
+ *
+ * <p>The entites' status are set to VALID because the entities parents and properties do not have
+ * to be retrieved.
+ */
+@JobAnnotation(flag = "names", time = JobExecutionTime.INIT)
+public class RetriveAllNames extends FlagJob {
+
+  @Override
+  protected void job(String value) {
+
+    GetAllNames t = execute(new GetAllNames());
+    for (EntityInterface e : t.getEntities()) {
+      if (e.hasPermission(EntityPermission.RETRIEVE_ENTITY)) {
+        this.getContainer().add(e);
+        e.setEntityStatus(EntityStatus.VALID);
+      }
+    }
+  }
+}
diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java
index 8df3bc2f8b798a8495f9bb670fa7ce23c5eba9c2..30dd77e0c0fc7f97f85db7d45c00cf762badc695 100644
--- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java
+++ b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java
@@ -5,7 +5,6 @@ import static caosdb.server.permissions.Role.ANONYMOUS_ROLE;
 import caosdb.server.accessControl.UserSources;
 import caosdb.server.database.exceptions.EntityDoesNotExistException;
 import caosdb.server.datatype.SingleValue;
-import caosdb.server.entity.Entity;
 import caosdb.server.entity.EntityInterface;
 import caosdb.server.entity.Message;
 import caosdb.server.entity.Message.MessageType;
@@ -489,7 +488,7 @@ public class AWIBoxLoan extends AWIBoxLoanModel {
     return false;
   }
 
-  boolean checkEmail(Entity entity) {
+  boolean checkEmail(EntityInterface entity) {
     runJobFromSchedule(entity, CheckPropValid.class);
     for (Property p : entity.getProperties()) {
       if (Objects.equals(p.getId(), getEmailID()) && p.getValue() instanceof SingleValue) {
@@ -505,7 +504,7 @@ public class AWIBoxLoan extends AWIBoxLoanModel {
     return false;
   }
 
-  private boolean checkUniqueName(Entity entity) {
+  private boolean checkUniqueName(EntityInterface entity) {
     String firstName = null;
     String lastName = null;
     Query q =
diff --git a/src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java b/src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bfca90bf8e0c060caf7ca97b85ceaf7d0d35f5c
--- /dev/null
+++ b/src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java
@@ -0,0 +1,18 @@
+package caosdb.server.resource.transaction;
+
+import caosdb.server.entity.container.RetrieveContainer;
+import caosdb.server.resource.transaction.handlers.GetNamesRequestHandler;
+import caosdb.server.resource.transaction.handlers.RequestHandler;
+
+public class EntityNamesResource extends EntityResource {
+
+  public EntityNamesResource() {
+    // only get is allowed
+    super(true, false, false, false);
+  }
+
+  @Override
+  protected RequestHandler<RetrieveContainer> getGetRequestHandler() {
+    return new GetNamesRequestHandler();
+  }
+}
diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java b/src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..f69c112880e833d0c981b903562889e377fe6f23
--- /dev/null
+++ b/src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java
@@ -0,0 +1,13 @@
+package caosdb.server.resource.transaction.handlers;
+
+import caosdb.server.entity.container.RetrieveContainer;
+import caosdb.server.resource.transaction.EntityResource;
+
+public class GetNamesRequestHandler extends RequestHandler<RetrieveContainer> {
+
+  /** Adds the `names` flag to the RetrieveContainer which triggers the RetrieveAllNames job. */
+  @Override
+  public void handle(EntityResource t, RetrieveContainer container) throws Exception {
+    container.getFlags().put("names", null);
+  }
+}
diff --git a/src/main/java/caosdb/server/transaction/Update.java b/src/main/java/caosdb/server/transaction/Update.java
index 8edd27d0aa0250ffebadc8d9a9639490daf1e2c7..b9e6e8de19f137014d10d1c6516c07ca2acabf8e 100644
--- a/src/main/java/caosdb/server/transaction/Update.java
+++ b/src/main/java/caosdb/server/transaction/Update.java
@@ -58,7 +58,7 @@ public class Update extends WriteTransaction<UpdateContainer> {
   protected void init() throws Exception {
     // collect all ids of the entities which are to be updated.
     final TransactionContainer oldContainer = new TransactionContainer();
-    for (final Entity entity : getContainer()) {
+    for (final EntityInterface entity : getContainer()) {
       // entity has no id -> it cannot be updated.
       if (!entity.hasId()) {
         entity.addError(ServerMessages.ENTITY_HAS_NO_ID);
diff --git a/src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java b/src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c67d5cba56cd3bfb1516788a0187f9bc673f5e6
--- /dev/null
+++ b/src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java
@@ -0,0 +1,65 @@
+package caosdb.server.database.backend.transactions;
+
+import static org.junit.Assert.assertEquals;
+
+import caosdb.server.CaosDBServer;
+import caosdb.server.database.BackendTransaction;
+import caosdb.server.database.access.Access;
+import caosdb.server.database.backend.interfaces.GetAllNamesImpl;
+import caosdb.server.database.backend.transaction.GetAllNames;
+import caosdb.server.database.misc.TransactionBenchmark;
+import caosdb.server.database.proto.SparseEntity;
+import caosdb.server.entity.EntityInterface;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestGetAllNames {
+
+  public static class GetAllNamesBackend implements GetAllNamesImpl {
+
+    @Override
+    public void setTransactionBenchmark(TransactionBenchmark b) {}
+
+    @Override
+    public TransactionBenchmark getBenchmark() {
+      return null;
+    }
+
+    @Override
+    public List<SparseEntity> execute() {
+      ArrayList<SparseEntity> ret = new ArrayList<>();
+
+      for (int i = 0; i < 10; i++) {
+
+        SparseEntity e = new SparseEntity();
+        e.role = "RecordType";
+        e.name = "Test" + Integer.toString(i);
+        e.acl = "";
+        ret.add(e);
+      }
+      return ret;
+    }
+
+    public GetAllNamesBackend(Access access) {}
+  }
+
+  @BeforeClass
+  public static void setup() throws IOException {
+    CaosDBServer.initServerProperties();
+    BackendTransaction.init();
+    BackendTransaction.setImpl(GetAllNamesImpl.class, GetAllNamesBackend.class);
+  }
+
+  @Test
+  public void test() {
+    GetAllNames getAllNames = new GetAllNames();
+    getAllNames.executeTransaction();
+    List<EntityInterface> entities = getAllNames.getEntities();
+    assertEquals(entities.size(), 10);
+    EntityInterface first = entities.get(0);
+    assertEquals(first.getName(), "Test0");
+  }
+}