diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07467d9e119418dfa74b83a539ed3572678d0425..9bd479a63f27e29fd930ae5f087692f1d8d4307f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Added
 
 * An openAPI specification of the XML api
+* New server configuration option `SERVER_BIND_ADDRESS`, which is the address to listen to. See [server.conf](conf/core/server.conf).
 
 ### Changed
 
@@ -17,14 +18,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Removed
 
+* `IdOnly` flag (see https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/187).
+  The flags was not working anyways. However, `SELECT id FROM ...` queries are
+  now optimized in the way the `IdOnly` flag was supposed to do.
+
 ### Fixed
 
+* #181 CQL's `UPDATED` filter.
+  (https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/181)
+* #183 No reasonable error when using bad datetime format.
+  (https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/183)
 * #127 "nan" as value (list item) in properties with data type "LIST<DOUBLE>"
   return with "Cannot parse value to double" error.
 * #170 Updating an abstract list-type property with a default value fails with
   "unkown error".
 * #145 Documentation of importances and inheritance
 * Missing sources of the easy-unit dependency.
+* #178 Formatting of tables in documentation
 
 ### Security
 
diff --git a/README_SETUP.md b/README_SETUP.md
index afc63592e7797adafa8cd58df37d0aff0a8d5b15..95805257d3ca285abeb4fcb2e3901cba291c57c0 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -1,5 +1,7 @@
 # Getting Started with the CaosDB Server
-Here, you find information on requirements, the installation, configuration and more.
+
+Here, you find information on requirements, the installation, configuration and
+more.
 
 ## Requirements
 
@@ -9,6 +11,7 @@ Here, you find information on requirements, the installation, configuration and
 * caosdb-mysqlbackend=3.0
 
 ### Third-party Software
+
 * `>=Java 8`
 * `>=Apache Maven 3.0.4`
 * `>=Python 3.4`
@@ -24,6 +27,7 @@ Here, you find information on requirements, the installation, configuration and
 - `easy-units` >= 0.0.1    https://gitlab.com/timm.fitschen/easy-units
 
 #### Install the requirements on Debian
+
 On Debian, the required packages can be installed with:
 
     apt-get install git make mariadb-server maven openjdk-11-jdk-headless \
@@ -80,7 +84,8 @@ server:
      Replace `localhost` by your host name, if you want.
    - `keytool -importkeystore -srckeystore caosdb.jks -destkeystore caosdb.p12 -deststoretype PKCS12 -srcalias selfsigned`
    - Export the public part only: `openssl pkcs12 -in caosdb.p12 -nokeys -out cert.pem`.
-     The resulting `cert.pem` can safely be given to users to allow ssl verification.
+     The resulting `cert.pem` can safely be given to users to allow ssl
+     verification.
    - You can check the content of the certificate with `openssl x509 -in cert.pem -text`
 
    Alternatively, you can create a keystore from certificate files that you already have:
@@ -88,13 +93,16 @@ server:
    - `keytool -importkeystore -srckeystore all-certs.pkcs12 -srcstoretype PKCS12  -deststoretype pkcs12 -destkeystore caosdb.jks`
 3. Install/configure the MySQL back-end: see the `README_SETUP.md` of the
    `caosdb-mysqlbackend` repository
-4. Create an authtoken config (e.g. copy `conf/core/authtoken.example.yaml` to `conf/ext/authtoken.yml` and change it)
+4. Create an authtoken config (e.g. copy `conf/core/authtoken.example.yaml` to
+   `conf/ext/authtoken.yml` and change it)
 5. Copy `conf/core/server.conf` to `conf/ext/server.conf` and change it
    appropriately:
     * Setup for MySQL back-end:
       specify the fields `MYSQL_USER_NAME`, `MYSQL_USER_PASSWORD`,
       `MYSQL_DATABASE_NAME`, and `MYSQL_HOST`.
-    * Choose the ports under which CaosDB will be accessible.
+    * Choose the host and ports under which CaosDB will be accessible. The host
+      is the IP address the server should listen on. Blank (the default) means
+      all interfaces, and `127.0.0.1` means only localhost.
     * Setup the SSL certificate: Assuming that there is an appropriate `Java Key
       Store` file (see above), change the fields `CERTIFICATES_KEY_PASSWORD`,
       `CERTIFICATES_KEY_STORE_PATH`, and `CERTIFICATES_KEY_STORE_PASSWORD`.
@@ -150,6 +158,9 @@ type `https://localhost:10443` in your Browser, assuming you used 10443 as port.
 Note, that you will get a security warning if you are using a self-signed
 certificate.
 
+You can use `make run-single` to directly start the server without rebuilding
+sources (if you called `make run` previously).
+
 ## Run Unit Tests
 
 `$ make test`
@@ -213,3 +224,60 @@ cd javasphinx
 git checkout 659209069603a
 pip3 install .
 ```
+
+## Installation under special conditions
+
+### Installation without or with restricted internet connection on the host system
+
+It is of course possible to install CaosDB on servers which do not have an
+internet connection or only have limited access to the internet.
+However, maven, which is used to build the CaosDB server, typically accesses
+the internet very often, and some reconfiguration might be necessary to prevent
+timeout issues and similar headache.
+
+A recommendation to proceed is:
+- Clone the repositories (caosdb-server, caosdb-mysqlbackend and subrepository
+  caosdb-webui) on a second machine that has internet connection.
+- Run `make install` and `make run` in the caosdb-server repository. This will
+  download all required dependencies and setup all maven-related artifacts in
+  a folder called `.m2` typically located in the home directory.
+- In addition to copying over the repositories for the server, mysqlbackend and
+  webui to the target host machine, also copy the complete `.m2` folder to the
+  **home directory of the user that is running the CaosDB server**.
+- On the host machine, open the file `pom.xml` in the server repository.
+- Look for the section `<repositories>`. There should be a `<respository>` with
+  `<id>local-maven-repo</id>`. It should be moved on top of the list of
+  repositories, so that the xml block appears directly after `<repositories>`
+  and before the repository maven-central.
+
+## Troubleshooting / FAQ
+
+### I set up and run the server, but I get an error that XSLT parsing failed in the WebUI
+
+You probably forgot to `make` the webui.
+
+Make sure that you:
+- Installed the WebUI according to the section [Web UI]
+- Run `make install` in the webui sub folder
+
+### How can I run the CaosDB server using ports 443 and 80?
+
+On standard linux setups, ports 443 and 80 cannot be opened by non-root processes.
+
+There are multiple solutions for this problem:
+- Use iptables to redirect a low port to a high port.
+- Use `CAP_NET_BIND_SERVICE`.
+- Use authbind.
+
+Here are some resources to read about these options:
+- [Question on Stackoverflow](https://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-on-linux)
+- [Questoin on Superuser](https://superuser.com/questions/710253/allow-non-root-process-to-bind-to-port-80-and-443)
+- [iptables tutorial](https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#REDIRECTTARGET)
+
+Using authbind is a simple solution that is briefly described here:
+- Install the package authbind
+- Create (empty) files `/etc/authbind/byport/80` (and `.../443`), e.g. using `touch`
+- Grant execution permissions for the user who runs the server to the new files.
+- Run the CaosDB server using authbind with the `--deep` option:
+  `authbind --deep make run`. The `--deep` option is necessary because the
+  server starts a subprocess which actually opens the ports.
diff --git a/conf/core/server.conf b/conf/core/server.conf
index 088cb4c45955a5d1163cb6551dd57de9a91ce17b..64ba2f070104ac03c5a59b7556592ead795d1cd9 100644
--- a/conf/core/server.conf
+++ b/conf/core/server.conf
@@ -77,6 +77,10 @@ MYSQL_SCHEMA_VERSION=v5.0
 # The context root is a prefix which allows running multiple instances of CaosDB using the same
 # hostname and port. Must start with "/".
 CONTEXT_ROOT=
+# Server bind/host address, which is the address to listen to. Set to blank, or
+# 0.0.0.0 in IPv4, to listen to all. Set to 127.0.0.1 to make it available to
+# localhost only.
+SERVER_BIND_ADDRESS=
 # HTTPS port of this server instance.
 SERVER_PORT_HTTPS=443
 # HTTP port of this server instance.
diff --git a/src/doc/specification/Authentication.md b/src/doc/specification/Authentication.md
deleted file mode 100644
index 6040d3792db553aea8cdd7206367be2bfec9257b..0000000000000000000000000000000000000000
--- a/src/doc/specification/Authentication.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Authentication
- Some features of CaosDB are available to registered users only. Making any changes to the data stock via HTTP requires authentication by `username` _plus_ `password`. They are to be send as a HTTP header, while the password is to be hashed by the sha512 algorithm:
-
-| `username:` | `$username` | 
-|-------------|-------------|-
-| `password:` | `$SHA512ed_password` |
-
-
-## Sessions
-
-### Login
-
-#### Request Challenge
-
- * `GET http://host:port/mpidsserver/login?username=$username`
- * `GET http://host:port/mpidsserver/login` with `username` header
-
-*no password required to be sent over http*
-
-The request returns an AuthToken with a login challenge as a cookie. The AuthToken is a dictionary of the following form:
-
-
-        {scope=$scope;
-        mode=LOGIN;
-        offerer=$offerer;
-        auth=$auth
-        expires=$expires;
-        date=$date;
-        hash=$hash;
-        session=$session;
-        }
-
- $scope:: A uri pattern string. Example: ` {**/*} `
- $mode:: `ONETIME`, `SESSION`, or `LOGIN`
- $offerer:: A valid username
- $auth:: A valid username
- $expires:: A `YYYY-MM-DD HH:mm:ss[.nnnn]` date string
- $date:: A `YYYY-MM-DD HH:mm:ss[.nnnn]` date string
- $hash:: A string
- $session:: A string
-
-The challenge is solved by concatenating the `$hash` string and the user's `$password` string and calculating the sha512 hash of both. Pseudo code:
-
-
-        $solution = sha512($hash + sha512($password))
-
-#### Send Solution
-
-The old $hash string in the cookie has to be replaces by $solution and the cookie is to be send with the next request:
-
-`PUT http://host:port/mpidsserver/login`
-
-The server will return the user's entity in the HTTP body, e.g.
-
-
-        <Response ...>
-          <User name="$username" ...>
-            ...
-          </User>
-        </Response>
-
-and a new AuthToken with `$mode=SESSION` and a new expiration date and so on. This AuthToken cookie is to be send with every request.
-
-### Logout
-
-Send 
-
-`PUT http://host:port/mpidsserver/logout`
-
-with a valid AuthToken cookie. No new AuthToken will be returned and no AuthToken with that `$session` will be accepted anymore.
-
-### Commandline solution with `curl` ##
-
-To use curl for talking with the server, first save your password into a variable:
-`PW=$(cat)`
-
-The create a cookie in `cookie.txt` like this (note that this makes your password visible for a short time to everyone on your system:
-`curl -X POST -c cookie.txt -D head.txt -H "Content-Type: application/x-www-form-urlencoded" -d username=<USERNAME> -d password="$PW" --insecure "https://<SERVER>/login`
-
-To use the cookie, pass it on with later requests:
-`curl -X GET -b cookie.txt --insecure "https://<SERVER>/Entity/12345"`
-
diff --git a/src/doc/specification/Authentication.rst b/src/doc/specification/Authentication.rst
new file mode 100644
index 0000000000000000000000000000000000000000..93d68c20171e55dad663ece719a78008793a4191
--- /dev/null
+++ b/src/doc/specification/Authentication.rst
@@ -0,0 +1,111 @@
+Authentication
+==============
+
+Some features of CaosDB are available to registered users only. Making any
+changes to the data stock via HTTP requires authentication by ``username`` **plus**
+``password``. They are to be send as a HTTP header, while the password is to be
+hashed by the sha512 algorithm:
+
+============= ======================
+username:     password:
+============= ======================
+``$username`` ``$SHA512ed_password``
+============= ======================
+
+Sessions
+--------
+
+Login
+^^^^^
+
+Request Challenge
+^^^^^^^^^^^^^^^^^
+
+* ``GET http://host:port/mpidsserver/login?username=$username``
+* ``GET http://host:port/mpidsserver/login`` with ``username`` header
+
+**No password is required to be sent over http.**
+
+The request returns an AuthToken with a login challenge as a cookie.
+The AuthToken is a dictionary of the following form:
+
+.. code-block::
+
+   {scope=$scope;
+    mode=LOGIN;
+    offerer=$offerer;
+    auth=$auth
+    expires=$expires;
+    date=$date;
+    hash=$hash;
+    session=$session;
+   }
+
+where
+
+* ``$scope`` :: A uri pattern string. Example: ``{ **/* }``
+* ``$mode`` :: ``ONETIME``, ``SESSION``, or ``LOGIN``
+* ``$offerer`` :: A valid username
+* ``$auth`` :: A valid username
+* ``$expires`` :: A ``YYYY-MM-DD HH:mm:ss[.nnnn]`` date string
+* ``$date`` :: A ``YYYY-MM-DD HH:mm:ss[.nnnn]`` date string
+* ``$hash`` :: A string
+* ``$session`` :: A string
+
+The challenge is solved by concatenating the ``$hash`` string and
+the user's ``$password`` string and calculating the sha512 hash of both.
+Pseudo code:
+
+.. code-block::
+
+   $solution = sha512($hash + sha512($password))
+
+Send Solution
+^^^^^^^^^^^^^
+
+The old ``$hash`` string in the cookie has to be replaces by ``$solution`` and
+ the cookie is to be send with the next request:
+
+``PUT http://host:port/mpidsserver/login``
+
+The server will return the user's entity in the HTTP body, e.g.
+
+.. code-block::
+
+   <Response ...>
+     <User name="$username" ...>
+      ...
+     </User>
+   </Response>
+
+and a new AuthToken with ``$mode=SESSION`` and a new expiration date and so
+on. This AuthToken cookie is to be send with every request.
+
+Logout
+^^^^^^
+
+Send
+
+``PUT http://host:port/mpidsserver/logout``
+
+with a valid AuthToken cookie. No new AuthToken will be returned and no
+AuthToken with that ``$session`` will be accepted anymore.
+
+Commandline solution with ``curl``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To use curl for talking with the server, first save your password into a
+variable: ``PW=$(cat)``
+
+The create a cookie in ``cookie.txt`` like this (note that this makes your
+password visible for a short time to everyone on your system:
+
+.. code-block:: sh
+
+   curl -X POST -c cookie.txt -D head.txt -H "Content-Type: application/x-www-form-urlencoded" -d username=<USERNAME> -d password="$PW" --insecure "https://<SERVER>/login
+
+To use the cookie, pass it on with later requests:
+
+.. code-block:: sh
+
+   curl -X GET -b cookie.txt --insecure "https://<SERVER>/Entity/12345"
diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java
index 87fd3048266098dca2ae1d5f46b6316be2453cd0..17bb1e500ed5aeffec25cf9aa2535150ceb40b4c 100644
--- a/src/main/java/org/caosdb/server/CaosDBServer.java
+++ b/src/main/java/org/caosdb/server/CaosDBServer.java
@@ -333,6 +333,13 @@ public class CaosDBServer extends Application {
   }
 
   private static void initWebServer() throws Exception {
+    /* For the host, the property can't be used directly since blank should mean
+    all interfaces, not localhost; which means replacing a blank value with
+    null. */
+    final String server_bind_address_property =
+        getServerProperty(ServerProperties.KEY_SERVER_BIND_ADDRESS);
+    final String server_bind_address =
+        server_bind_address_property.length() == 0 ? null : server_bind_address_property;
     final int port_https =
         Integer.parseInt(getServerProperty(ServerProperties.KEY_SERVER_PORT_HTTPS));
     final int port_http =
@@ -350,10 +357,15 @@ public class CaosDBServer extends Application {
         Integer.parseInt(getServerProperty(ServerProperties.KEY_MAX_CONNECTIONS));
 
     if (NO_TLS) {
-      runHTTPServer(port_http, initialConnections, maxTotalConnections);
+      runHTTPServer(server_bind_address, port_http, initialConnections, maxTotalConnections);
     } else {
       runHTTPSServer(
-          port_https, port_http, port_redirect_https, initialConnections, maxTotalConnections);
+          server_bind_address,
+          port_https,
+          port_http,
+          port_redirect_https,
+          initialConnections,
+          maxTotalConnections);
     }
     GRPCServer.startServer();
   }
@@ -372,7 +384,10 @@ public class CaosDBServer extends Application {
    * @throws Exception
    */
   private static void runHTTPServer(
-      final int port_http, final int initialConnections, final int maxTotalConnections)
+      final String server_bind_address,
+      final int port_http,
+      final int initialConnections,
+      final int maxTotalConnections)
       throws Exception {
     Engine.getInstance()
         .getRegisteredServers()
@@ -385,7 +400,7 @@ public class CaosDBServer extends Application {
         new Server(
             (Context) null,
             Arrays.asList(Protocol.HTTP),
-            null,
+            server_bind_address,
             port_http,
             (Restlet) null,
             "org.restlet.ext.jetty.HttpServerHelper");
@@ -422,6 +437,7 @@ public class CaosDBServer extends Application {
    * connections on `port_http` and redirect any http connections to `port_redirect_https`.
    *
    * @author Timm Fitschen
+   * @param server_bind_address IP address to listen on (null means all interfaces).
    * @param port_https Listen on this port for https connections.
    * @param port_http Listen on this port for http connections and send http-to-https redirect with
    *     different port.
@@ -429,6 +445,7 @@ public class CaosDBServer extends Application {
    * @throws Exception if problems occur starting up this server.
    */
   private static void runHTTPSServer(
+      final String server_bind_address,
       final int port_https,
       final int port_http,
       final int port_redirect_https,
@@ -445,7 +462,7 @@ public class CaosDBServer extends Application {
         new Server(
             (Context) null,
             Arrays.asList(Protocol.HTTPS),
-            null,
+            server_bind_address,
             port_https,
             (Restlet) null,
             "org.caosdb.server.CaosDBServerConnectorHelper");
@@ -456,7 +473,7 @@ public class CaosDBServer extends Application {
       logger.info("Redirecting to " + port_redirect_https);
       component
           .getServers()
-          .add(Protocol.HTTP, port_http)
+          .add(Protocol.HTTP, server_bind_address, port_http)
           .setNext(new HttpToHttpsRedirector(port_redirect_https));
     }
 
diff --git a/src/main/java/org/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java
index 9e62357d2252cb8ff5c43f66e296d5fb125fae24..34899f7551ccc8ac99e6f2246eeb154c37171e53 100644
--- a/src/main/java/org/caosdb/server/ServerProperties.java
+++ b/src/main/java/org/caosdb/server/ServerProperties.java
@@ -60,6 +60,7 @@ public class ServerProperties extends Properties {
   public static final String KEY_CONTEXT_ROOT = "CONTEXT_ROOT";
   public static final String KEY_POLICY_COMPONENT = "POLICY_COMPONENT";
 
+  public static final String KEY_SERVER_BIND_ADDRESS = "SERVER_BIND_ADDRESS";
   public static final String KEY_SERVER_PORT_HTTPS = "SERVER_PORT_HTTPS";
   public static final String KEY_SERVER_PORT_HTTP = "SERVER_PORT_HTTP";
   public static final String KEY_REDIRECT_HTTP_TO_HTTPS_PORT = "REDIRECT_HTTP_TO_HTTPS_PORT";
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java
index 6282ede52aa514353c21f0b8dd3345a85305725b..32f628459b4a8e3a23b9ac3d047e723d7a837c28 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java
@@ -26,6 +26,8 @@ import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.entity.EntityInterface;
+import org.caosdb.server.entity.InsertEntity;
+import org.caosdb.server.entity.UpdateEntity;
 import org.caosdb.server.entity.container.TransactionContainer;
 import org.caosdb.server.utils.EntityStatus;
 
@@ -60,7 +62,8 @@ public class InsertTransactionHistory extends BackendTransaction {
 
     for (final EntityInterface e : this.container) {
       if (e.getEntityStatus() == EntityStatus.DELETED
-          || e.getEntityStatus() == EntityStatus.VALID) {
+          || (e instanceof UpdateEntity && e.getEntityStatus() == EntityStatus.QUALIFIED)
+          || (e instanceof InsertEntity && e.getEntityStatus() == EntityStatus.VALID)) {
 
         t.execute(
             e.getClass().getSimpleName().replace("Entity", ""),
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index 6bac0ff187fe2a08d2d0c1c7450ac954bc023d5e..e42b854e3284017059f8d0f6bf83a70ddfdfc165 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -101,6 +101,9 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
    * @param selections
    */
   public void retrieveFullEntity(EntityInterface e, List<Selection> selections) {
+    if (!needMoreThanId(selections)) {
+      return;
+    }
     execute(new RetrieveSparseEntity(e));
 
     if (e.getEntityStatus() == EntityStatus.VALID) {
@@ -108,8 +111,13 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
       if (e.getRole() == Role.QueryTemplate) {
         execute(new RetrieveQueryTemplateDefinition(e));
       }
-      execute(new RetrieveParents(e));
-      execute(new RetrieveProperties(e));
+      if (needParents(selections)) {
+        execute(new RetrieveParents(e));
+      }
+
+      if (needProperties(selections)) {
+        execute(new RetrieveProperties(e));
+      }
 
       // recursion! retrieveSubEntities calls retrieveFull sometimes, but with reduced selectors.
       if (selections != null && !selections.isEmpty()) {
@@ -118,6 +126,55 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     }
   }
 
+  /**
+   * Return true iff anything else than the id is needed for this retrieval.
+   *
+   * <p>The notorious case, where it is not necessary to retrieve the sparse entity is during
+   * `SELECT id FROM ...` queries.
+   */
+  private boolean needMoreThanId(List<Selection> selections) {
+    if (selections == null || selections.isEmpty()) {
+      return true;
+    } else if (selections.size() == 1 && selections.get(0).isId()) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Return true iff the properties need to be retrieved.
+   *
+   * <p>It is not necessary during `SELECT parent, name, version, ...` queries where no actual
+   * properties are being selected.
+   */
+  private boolean needProperties(List<Selection> selections) {
+    if (selections == null || selections.isEmpty()) {
+      return true;
+    }
+    for (Selection s : selections) {
+      if (s.isProperty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+  /**
+   * Return true iff the parents need to be retrieved.
+   *
+   * <p>It is not necessary during `SELECT` queries that do not select the parent.
+   */
+  private boolean needParents(List<Selection> selections) {
+    if (selections == null || selections.isEmpty()) {
+      return true;
+    }
+    for (Selection s : selections) {
+      if (s.isParent()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Recursively resolve the reference values of the list of reference property `p` (but only the
    * selected sub-properties).
diff --git a/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java b/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java
index 574e40cb96097544a19cf46c4ad700e9ce442208..9c66f425ef0b867a3932b5b6fa85e5d88bf8f4a7 100644
--- a/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java
+++ b/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java
@@ -37,12 +37,19 @@ public class DateTimeDatatype extends AbstractDatatype {
     try {
       if (value instanceof UTCDateTime || value instanceof Date) {
         return (DateTimeInterface) value;
-      } else if (value instanceof GenericValue) {
-        return DateTimeFactory2.valueOf(((GenericValue) value).toDatabaseString());
+      }
+
+      DateTimeInterface result;
+      if (value instanceof GenericValue) {
+        result = DateTimeFactory2.valueOf(((GenericValue) value).toDatabaseString());
       } else {
-        return DateTimeFactory2.valueOf(value.toString());
+        result = DateTimeFactory2.valueOf(value.toString());
       }
-    } catch (final IllegalArgumentException e) {
+
+      // Test if this is storable
+      result.toDatabaseString();
+      return result;
+    } catch (final UnsupportedOperationException | IllegalArgumentException e) {
       throw ServerMessages.CANNOT_PARSE_DATETIME_VALUE;
     }
   }
diff --git a/src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java b/src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java
deleted file mode 100644
index 844468c5473b4d2dff6e59777f925f2701505749..0000000000000000000000000000000000000000
--- a/src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.jobs.core;
-
-import org.caosdb.server.entity.EntityInterface;
-import org.caosdb.server.jobs.FlagJob;
-import org.caosdb.server.jobs.JobAnnotation;
-import org.caosdb.server.jobs.TransactionStage;
-import org.caosdb.server.utils.EntityStatus;
-
-@JobAnnotation(flag = "IdOnly", stage = TransactionStage.PRE_TRANSACTION)
-public class RetrieveIdOnlyFlag extends FlagJob {
-
-  @Override
-  protected void job(final String value) {
-    if (value == null || value.equalsIgnoreCase("true")) {
-      for (final EntityInterface e : getContainer()) {
-        // do not retrieve this entity
-        e.setEntityStatus(EntityStatus.IGNORE);
-      }
-    }
-  }
-}
diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index eebd2b2e1bb4b7a594b4defc61671d9b09aec757..fa5754c65e0e89baf90774fa7def683ece66236b 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -32,12 +32,15 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.UUID;
 import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
@@ -75,6 +78,16 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
     private final String selector;
     private Selection subselection = null;
 
+    /**
+     * These magic non-properties are those which are in the results of a {@link
+     * RetrieveSparseEntity} transaction which is why they do not need to be retrieved with a {@link
+     * RetrieveEntityProperties} transaction.
+     */
+    static final Set<String> MAGIC_NON_PROPERTIES =
+        new HashSet<>(
+            Arrays.asList(
+                new String[] {"value", "parent", "id", "name", "description", "datatype"}));
+
     public Selection setSubSelection(final Selection sub) {
       if (this.subselection != null) {
         throw new UnsupportedOperationException("SubSelection is immutable!");
@@ -111,6 +124,29 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
       ret.setAttribute("name", toString());
       return ret;
     }
+
+    /**
+     * Return true iff this selector selects the parent of an entity. If not, the retrieval in
+     * {@link RetrieveFullEntityTransaction} might be optimized by not retrieving the parents at
+     * all.
+     */
+    public boolean isParent() {
+      return this.selector.equalsIgnoreCase("parent");
+    }
+
+    /**
+     * Return true iff this selector selects anything that is most likely a property. If not, the
+     * retrieval in {@link RetrieveFullEntityTransaction} might be optimized by not retrieving the
+     * properties at all.
+     */
+    public boolean isProperty() {
+      return !MAGIC_NON_PROPERTIES.contains(this.selector.toLowerCase());
+    }
+
+    /** Return true iff this selector selects the id of an entity. */
+    public boolean isId() {
+      return this.selector.equalsIgnoreCase("id");
+    }
   }
 
   public enum Role {