diff --git a/conanfile.py b/conanfile.py
index 04d2b1f527b0c5936c0c9a5c7d6d20a98446f1bb..3495107311d4e0d467313dc4d8b088a508349d55 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -14,9 +14,9 @@ class CaosdbConan(ConanFile):
     default_options = {"shared": False, "fPIC": True}
     generators = "cmake"
     requires = [
-        ("boost/1.76.0"),
+        ("boost/1.77.0"),
         ("gtest/1.11.0"),
-        ("grpc/1.38.0"),
+        ("grpc/1.39.1"),
     ]
     exports = "*.cpp", "*.h", "*.cmake", "*CMakeLists.txt", "*.in", "*.proto", "*.c"
     exports_sources = "src", "doc", "include", "test", "cmake", "proto"
diff --git a/include/caosdb/authentication.h b/include/caosdb/authentication.h
index 070346c9366d89e7476f125b74feaea4ceb40a32..8e98a17e6d94fe118cf2fc478efbbf77733be4a6 100644
--- a/include/caosdb/authentication.h
+++ b/include/caosdb/authentication.h
@@ -28,10 +28,10 @@
  * @brief Configuration and setup of the client authentication.
  */
 #include "caosdb/utility.h"                            // for base64_encode
-#include "grpcpp/impl/codegen/interceptor.h"           // for Status
-#include "grpcpp/impl/codegen/security/auth_context.h" // for AuthContext
-#include "grpcpp/impl/codegen/status.h"                // for Status
-#include "grpcpp/impl/codegen/string_ref.h"            // for string_ref
+#include <grpcpp/impl/codegen/interceptor.h>           // for Status
+#include <grpcpp/impl/codegen/security/auth_context.h> // for AuthContext
+#include <grpcpp/impl/codegen/status.h>                // for Status
+#include <grpcpp/impl/codegen/string_ref.h>            // for string_ref
 #include <grpcpp/security/credentials.h>               // for CallCredentials
 #include <map>                                         // for multimap
 #include <memory>                                      // for shared_ptr
diff --git a/include/caosdb/certificate_provider.h b/include/caosdb/certificate_provider.h
index e7d7a156efeaf05435fd3ccb8029549a82e38442..197ab7277a8110063351718897b65c8db3289768 100644
--- a/include/caosdb/certificate_provider.h
+++ b/include/caosdb/certificate_provider.h
@@ -22,7 +22,8 @@
 #ifndef CAOSDB_CERTIFICATE_PROVIDER_H
 #define CAOSDB_CERTIFICATE_PROVIDER_H
 
-#include "boost/filesystem/path.hpp" // for path
+#include <boost/filesystem/path.hpp> // for path
+
 namespace caosdb::configuration {
 using boost::filesystem::path;
 
diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h
index 2c521e7b0f36c351dabd6f7341ea3bb393fd402c..83b47810e7756555c201b57538b6f8ba738d1e43 100644
--- a/include/caosdb/configuration.h
+++ b/include/caosdb/configuration.h
@@ -21,21 +21,21 @@
 
 #ifndef CAOSDB_CONFIGURATION_H
 #define CAOSDB_CONFIGURATION_H
-#include "boost/filesystem/operations.hpp" // for exists
-#include "boost/filesystem/path.hpp"       // for path
-#include "boost/json/object.hpp"           // for object
-#include "boost/json/value.hpp"            // for value
-#include "boost/json/value_ref.hpp"        // IWYU pragma: keep
-// IWYU pragma: no_include "boost/json/fwd.hpp"
 #include "caosdb/authentication.h"       // for Authenticator, PlainPassw...
 #include "caosdb/certificate_provider.h" // for CertificateProvider, path
 #include "caosdb/exceptions.h"           // for ConfigurationError
-#include "caosdb/logging.h"
+#include "caosdb/logging.h"              // for CAOSDB_LOG_...
 #include "caosdb/utility.h"              // for load_json_file
-#include "grpcpp/security/credentials.h" // for ChannelCredentials
-#include <iosfwd>                        // for ostream
-#include <memory>                        // for unique_ptr, shared_ptr
-#include <string>                        // for string
+// IWYU pragma: no_include "boost/json/fwd.hpp"
+#include <boost/filesystem/operations.hpp> // for exists
+#include <boost/filesystem/path.hpp>       // for path
+#include <boost/json/object.hpp>           // for object
+#include <boost/json/value.hpp>            // for value
+#include <boost/json/value_ref.hpp>        // IWYU pragma: keep
+#include <grpcpp/security/credentials.h>   // for ChannelCredentials
+#include <iosfwd>                          // for ostream
+#include <memory>                          // for unique_ptr, shared_ptr
+#include <string>                          // for string
 
 namespace caosdb::configuration {
 using boost::filesystem::exists;
diff --git a/include/caosdb/connection.h b/include/caosdb/connection.h
index d3ed0945e0022f29e6097fb4ea2d9207c3258987..4eadde0ac281fb61bb5eca49b5b64cb8baedeccb 100644
--- a/include/caosdb/connection.h
+++ b/include/caosdb/connection.h
@@ -27,10 +27,6 @@
  * @date 2021-05-18
  * @brief Configuration and setup of the connection.
  */
-#include <map>                                   // for map
-#include <memory>                                // for shared_ptr, unique_ptr
-#include <string>                                // for string, basic_string
-#include "boost/filesystem/path.hpp"             // for path
 #include "caosdb/authentication.h"               // for Authenticator
 #include "caosdb/configuration.h"                // for ConnectionConfigura...
 #include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe...
@@ -38,7 +34,11 @@
 #include "caosdb/info/v1alpha1/main.grpc.pb.h"   // for GeneralInfoService:...
 #include "caosdb/transaction.h"                  // for Transaction
 #include "caosdb/transaction_status.h"           // for TransactionStatus
-#include "grpcpp/channel.h"                      // for Channel
+#include <boost/filesystem/path.hpp>             // for path
+#include <grpcpp/channel.h>                      // for Channel
+#include <map>                                   // for map
+#include <memory>                                // for shared_ptr, unique_ptr
+#include <string>                                // for string, basic_string
 
 namespace caosdb::connection {
 using boost::filesystem::path;
diff --git a/include/caosdb/data_type.h b/include/caosdb/data_type.h
index 42d376698872e086c05a5905484e2f63c11dd346..c084a338272532db652b4d7df85cfa42940c6bb1 100644
--- a/include/caosdb/data_type.h
+++ b/include/caosdb/data_type.h
@@ -140,6 +140,21 @@ protected:
 
 class DataType : public ScalarProtoMessageWrapper<ProtoDataType> {
 public:
+  /**
+   * Copy constructor.
+   */
+  inline DataType(const DataType &other)
+    : DataType(ProtoMessageWrapper<ProtoDataType>::CopyProtoMessage(other.wrapped)) {}
+
+  /**
+   * Move constructor.
+   */
+  inline DataType(DataType &&other) : DataType(other.wrapped) {
+    other.wrapped = nullptr;
+    other.list_data_type.reset();
+    other.reference_data_type.reset();
+  }
+
   DataType(ProtoDataType *wrapped) : ScalarProtoMessageWrapper<ProtoDataType>(wrapped) {}
   DataType() : ScalarProtoMessageWrapper<ProtoDataType>(static_cast<ProtoDataType *>(nullptr)) {}
   /**
@@ -227,6 +242,37 @@ public:
     return this->wrapped == other.wrapped;
   }
 
+  /**
+   * Copy assignment operator.
+   */
+  inline auto operator=(const DataType &other) -> DataType & {
+    if (this != &other) {
+      this->reference_data_type.reset();
+      this->list_data_type.reset();
+      if (other.wrapped != nullptr) {
+        this->wrapped = ProtoMessageWrapper<ProtoDataType>::CopyProtoMessage(other.wrapped);
+      } else {
+        this->wrapped = nullptr;
+      }
+    }
+    return *this;
+  }
+
+  /**
+   * Move assignment operator.
+   */
+  inline auto operator=(DataType &&other) -> DataType & {
+    if (this != &other) {
+      this->wrapped = other.wrapped;
+      other.wrapped = nullptr;
+      other.reference_data_type.reset();
+      this->reference_data_type.reset();
+      other.list_data_type.reset();
+      this->list_data_type.reset();
+    }
+    return *this;
+  }
+
   friend class Entity;
   friend class Property;
 
diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index 6de939c37f19d9419815dcb8b7001fd19050133f..08378065895c15f494ba5a6bcf1592bb8e6c2284 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -44,6 +44,7 @@
 #include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
 #include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
 #include <cstdint>                                     // for int64_t
+#include <google/protobuf/arena.h>                     // for Arena
 #include <google/protobuf/message.h>                   // for RepeatedPtrField
 #include <iosfwd>                                      // for streamsize
 #include <iterator>                                    // for iterator, output_iterato...
@@ -51,13 +52,14 @@
 #include <random>                                      // for mt19937, rand...
 #include <stdexcept>                                   // for out_of_range
 #include <string>                                      // for string, basic...
-#include <vector>                                      // for vector
 #include <utility>                                     // for move
+#include <vector>                                      // for vector
 
 namespace caosdb::entity {
 using boost::filesystem::exists;
 using boost::filesystem::is_directory;
 using caosdb::entity::v1alpha1::IdResponse;
+using google::protobuf::Arena;
 using ProtoParent = caosdb::entity::v1alpha1::Parent;
 using ProtoProperty = caosdb::entity::v1alpha1::Property;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
@@ -187,6 +189,32 @@ public:
     return result.append(std::string("]\n"));
   }
 
+  /**
+   * Return true if the underlying Protobuf messages have the same
+   * serialization.
+   */
+  inline auto operator==(const RepeatedPtrFieldWrapper<T, P> &other) const noexcept -> bool {
+    if (this->wrapped != nullptr && other.wrapped != nullptr && this->size() == other.size()) {
+      for (int i = 0; i < this->size(); i++) {
+        if (this->wrapped->Get(i).SerializeAsString() !=
+            other.wrapped->Get(i).SerializeAsString()) {
+          return false;
+        }
+      }
+      return true;
+    }
+    // last chance for "true": both nullptr?
+    return this->wrapped == other.wrapped;
+  }
+
+  /**
+   * Return true if the underlying Protobuf messages have a different
+   * serialization.
+   */
+  inline auto operator!=(const RepeatedPtrFieldWrapper<T, P> &other) const noexcept -> bool {
+    return !(*this == other);
+  }
+
 protected:
   RepeatedPtrFieldWrapper() : ProtoMessageWrapper<RepeatedPtrField<P>>(){};
   explicit inline RepeatedPtrFieldWrapper(RepeatedPtrField<P> *wrapped)
@@ -337,15 +365,13 @@ private:
  */
 class Messages : public RepeatedPtrFieldWrapper<Message, ProtoMessage> {
 public:
-  ~Messages();
-
   friend class Entity;
   // TODO(fspreck) Same here.
   // friend class Parent;
   // friend class Property;
 
 private:
-  inline Messages() : RepeatedPtrFieldWrapper(){};
+  inline Messages() : RepeatedPtrFieldWrapper<Message, ProtoMessage>(){};
 };
 
 /**
@@ -426,14 +452,13 @@ private:
  */
 class Parents : public RepeatedPtrFieldWrapper<Parent, ProtoParent> {
 public:
-  ~Parents() = default;
   friend class Entity;
 
 private:
-  inline Parents() : RepeatedPtrFieldWrapper(){};
+  inline Parents() : RepeatedPtrFieldWrapper<Parent, ProtoParent>(){};
   explicit inline Parents(
     ::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> *wrapped)
-    : RepeatedPtrFieldWrapper(wrapped){};
+    : RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped){};
 };
 
 /**
@@ -456,13 +481,10 @@ public:
   /**
    * Move constructor.
    */
-  inline Property(Property &&other) : Property() {
+  inline Property(Property &&other) : Property(other.wrapped) {
     CAOSDB_LOG_TRACE(logger_name) << "Property::Property(Property  &&) "
                                   << "- Move constructor";
-    this->wrapped = std::move(other.wrapped);
-    this->value.wrapped = this->wrapped->mutable_value();
-    this->data_type.wrapped = this->wrapped->mutable_data_type();
-
+    other.wrapped = nullptr;
     other.data_type.wrapped = nullptr;
     other.value.wrapped = nullptr;
   }
@@ -563,8 +585,12 @@ public:
     CAOSDB_LOG_TRACE(logger_name) << "Property::operator=(const Property &) "
                                   << "- Copy assignment operator";
     this->wrapped->CopyFrom(*other.wrapped);
-    this->value = Value(this->wrapped->mutable_value());
-    this->data_type = DataType(this->wrapped->mutable_data_type());
+
+    this->value.wrapped = (this->wrapped->has_value() ? this->wrapped->mutable_value()
+                                                      : static_cast<ProtoValue *>(nullptr));
+    this->data_type.wrapped =
+      (this->wrapped->has_data_type() ? this->wrapped->mutable_data_type()
+                                      : static_cast<ProtoDataType *>(nullptr));
     return *this;
   }
 
@@ -574,7 +600,8 @@ public:
   auto operator=(Property &&other) -> Property & {
     CAOSDB_LOG_TRACE(logger_name) << "Property::operator=(Property &&) "
                                   << "- Move assignment operator";
-    this->wrapped = std::move(other.wrapped);
+    this->wrapped = other.wrapped;
+    other.wrapped = nullptr;
     this->value = std::move(other.value);
     this->data_type = std::move(other.data_type);
     return *this;
@@ -606,7 +633,6 @@ private:
  */
 class Properties : public RepeatedPtrFieldWrapper<Property, ProtoProperty> {
 public:
-  ~Properties() = default;
   friend class Entity;
 
 private:
@@ -635,6 +661,9 @@ private:
  */
 class Entity : public ScalarProtoMessageWrapper<ProtoEntity> {
 public:
+  /**
+   * Copy constructor.
+   */
   inline Entity(const Entity &original)
     : Entity(ProtoMessageWrapper::CopyProtoMessage(original.wrapped)) {
     this->errors.wrapped->CopyFrom(*original.errors.wrapped);
@@ -650,7 +679,7 @@ public:
     properties.wrapped = this->wrapped->mutable_properties();
     parents.wrapped = this->wrapped->mutable_parents();
   };
-  explicit inline Entity(EntityResponse *response) : Entity(response->release_entity()) {
+  explicit inline Entity(EntityResponse *response) : Entity(response->mutable_entity()) {
     this->errors.wrapped->Swap(response->mutable_errors());
     this->warnings.wrapped->Swap(response->mutable_warnings());
     this->infos.wrapped->Swap(response->mutable_infos());
@@ -671,6 +700,56 @@ public:
     parents.wrapped = this->wrapped->mutable_parents();
   };
 
+  /**
+   * Move constructor.
+   */
+  explicit inline Entity(Entity &&original) : Entity(original.wrapped) {
+    original.wrapped = nullptr;
+    original.value.wrapped = nullptr;
+    original.data_type.wrapped = nullptr;
+    this->properties = std::move(original.properties);
+    this->parents = std::move(original.parents);
+    this->errors = std::move(original.errors);
+    this->warnings = std::move(original.warnings);
+    this->infos = std::move(original.infos);
+  };
+
+  /**
+   * Move assignment operator.
+   */
+  auto operator=(Entity &&other) -> Entity & {
+    this->wrapped = other.wrapped;
+    other.wrapped = nullptr;
+    this->data_type = std::move(other.data_type);
+    this->value = std::move(other.value);
+    this->properties = std::move(other.properties);
+    this->parents = std::move(other.parents);
+    this->file_descriptor = std::move(other.file_descriptor);
+    this->errors = std::move(other.errors);
+    this->warnings = std::move(other.warnings);
+    this->infos = std::move(other.infos);
+    return *this;
+  }
+
+  /**
+   * Copy assignment operator.
+   */
+  auto operator=(const Entity &other) -> Entity & {
+    this->wrapped->CopyFrom(*other.wrapped);
+    this->data_type = other.data_type;
+    this->value = other.value;
+    this->properties = other.properties;
+    this->parents = other.parents;
+    this->file_descriptor.local_path = boost::filesystem::path(other.file_descriptor.local_path);
+    this->file_descriptor.file_transmission_id->CopyFrom(
+      *other.file_descriptor.file_transmission_id);
+    this->file_descriptor.wrapped->CopyFrom(*other.file_descriptor.wrapped);
+    this->errors = other.errors;
+    this->warnings = other.warnings;
+    this->infos = other.infos;
+    return *this;
+  }
+
   [[nodiscard]] inline auto GetId() const noexcept -> const std::string & {
     return this->wrapped->id();
   };
@@ -787,6 +866,15 @@ public:
     infos.Clear();
   }
 
+  /**
+   * Return true if the other entity is equal to to this entity.
+   *
+   * This method ignores the errors, warnings and info messages.
+   */
+  inline auto operator==(const Entity &other) const noexcept -> bool {
+    return this->wrapped->SerializeAsString() == other.wrapped->SerializeAsString();
+  }
+
 private:
   inline auto GetNextFileId() -> std::string {
     std::string str = "0123456789abcdef";
@@ -802,6 +890,7 @@ private:
   static auto CreateMessagesField() -> RepeatedPtrField<ProtoMessage> *;
   auto SetId(const std::string &id) -> void;
   auto SetVersionId(const std::string &id) -> void;
+  auto inline GetArena() const -> Arena * { return get_arena(); }
 
 private:
   FileDescriptor file_descriptor;
diff --git a/include/caosdb/info.h b/include/caosdb/info.h
index cf2c879120becd8db211e85df39d62ac9ba1434e..e9e7e1773ab81a4676e5be65e904a8026a22d60a 100644
--- a/include/caosdb/info.h
+++ b/include/caosdb/info.h
@@ -28,6 +28,7 @@
  * @brief General information about the CaosDBServer.
  */
 #include "caosdb/info/v1alpha1/main.pb.h" // for VersionInfo
+#include "caosdb/protobuf_helper.h"       // for get_arena
 #include <cstdint>                        // for uint32_t
 #include <string>                         // for string
 
@@ -53,7 +54,11 @@ public:
    * CaosDBConnection::GetVersionInfo() instead to get the version of the
    * server behind the given connection.
    */
-  explicit inline VersionInfo(ProtoVersionInfo *info) : info(info){};
+  explicit inline VersionInfo(ProtoVersionInfo *info) : info(info) {
+    if (this->info->GetArena() == nullptr) {
+      caosdb::utility::get_arena()->Own(this->info);
+    }
+  };
   [[nodiscard]] inline auto GetMajor() const -> int32_t { return this->info->major(); }
   [[nodiscard]] inline auto GetMinor() const -> int32_t { return this->info->minor(); }
   [[nodiscard]] inline auto GetPatch() const -> int32_t { return this->info->patch(); }
@@ -63,8 +68,7 @@ public:
   [[nodiscard]] inline auto GetBuild() const -> const std::string & { return this->info->build(); }
 
 private:
-  /// This object is the owner of the Protobuf VersionInfo message.
-  std::unique_ptr<ProtoVersionInfo> info;
+  ProtoVersionInfo *info;
 };
 
 } // namespace caosdb::info
diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h
index 35c5fdfa1a72ba5f55933f3bd99aa93f313c3e33..7b5a605044521ba33ab1327e96889be3aef6345e 100644
--- a/include/caosdb/logging.h
+++ b/include/caosdb/logging.h
@@ -24,12 +24,11 @@
 #define CAOSDB_LOGGING_H
 
 #include "caosdb/log_level.h"                            // for CAOSDB_LOG_...
-#include "boost/log/sources/global_logger_storage.hpp"   // for BOOST_LOG_I...
-#include "boost/log/sources/record_ostream.hpp"          // IWYU pragma: keep
-#include "boost/log/sources/severity_channel_logger.hpp" // for BOOST_LOG_C...
-#include "boost/log/utility/setup/settings.hpp"          // for settings
-#include "boost/smart_ptr/intrusive_ptr.hpp"             // for intrusive_ptr
-#include "boost/smart_ptr/intrusive_ref_counter.hpp"     // for intrusive_p...
+#include <boost/log/sources/record_ostream.hpp>          // IWYU pragma: keep
+#include <boost/log/sources/severity_channel_logger.hpp> // for BOOST_LOG_C...
+#include <boost/log/utility/setup/settings.hpp>          // for settings
+#include <boost/smart_ptr/intrusive_ptr.hpp>             // for intrusive_ptr
+#include <boost/smart_ptr/intrusive_ref_counter.hpp>     // for intrusive_p...
 #include <memory>                                        // for shared_ptr
 #include <string>                                        // for string
 #include <vector>                                        // for vector
@@ -40,7 +39,24 @@ const std::string logger_name = "caosdb::logging";
 
 typedef boost::log::sources::severity_channel_logger_mt<int, std::string> boost_logger_class;
 
-BOOST_LOG_GLOBAL_LOGGER(logger, boost_logger_class)
+class _logger {
+public:
+  static boost_logger_class &get() { return *_logger::GetInstance()._logger_instance; }
+  static void destroy() {
+    auto &instance = _logger::GetInstance();
+    delete instance._logger_instance;
+  }
+
+private:
+  _logger() { this->_logger_instance = new boost_logger_class(); };
+  static _logger &GetInstance() {
+    static _logger instance;
+    return instance;
+  }
+  boost_logger_class *_logger_instance;
+};
+
+auto inline get_logger() -> boost_logger_class & { return _logger::get(); }
 
 /**
  * This class stores the integer log level.
@@ -187,17 +203,17 @@ void caosdb_log_trace(const char *channel, const char *msg);
 } // namespace caosdb::logging
 
 #define CAOSDB_LOG_FATAL(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_FATAL)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_FATAL)
 #define CAOSDB_LOG_ERROR(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_ERROR)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_ERROR)
 #define CAOSDB_LOG_WARN(Channel)                                                                   \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_WARN)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_WARN)
 #define CAOSDB_LOG_INFO(Channel)                                                                   \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_INFO)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_INFO)
 #define CAOSDB_LOG_DEBUG(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_DEBUG)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_DEBUG)
 #define CAOSDB_LOG_TRACE(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_TRACE)
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), Channel, CAOSDB_LOG_LEVEL_TRACE)
 
 #define CAOSDB_LOG_ERROR_AND_RETURN_STATUS(Channel, StatusCode, Message)                           \
   CAOSDB_LOG_ERROR(Channel) << "StatusCode (" << StatusCode << ") "                                \
diff --git a/include/caosdb/protobuf_helper.h b/include/caosdb/protobuf_helper.h
index 4dfc11c396ded34db6bb2cbed2c938a5402dd7c7..63b2c54cdfaae5eef33705ac7074e11c1caf3653 100644
--- a/include/caosdb/protobuf_helper.h
+++ b/include/caosdb/protobuf_helper.h
@@ -70,11 +70,7 @@ public:
    * serialization.
    */
   inline auto operator!=(const ProtoMessageWrapper<P> &other) const noexcept -> bool {
-    if (this->wrapped != nullptr && other.wrapped != nullptr) {
-      return this->wrapped->SerializeAsString() != other.wrapped->SerializeAsString();
-    }
-    // only one is nullptr?
-    return this->wrapped != other.wrapped;
+    return !(*this == other);
   }
 
 protected:
diff --git a/src/caosdb/authentication.cpp b/src/caosdb/authentication.cpp
index 50ff24455ac87227f475775974abae1228fc50d3..ecfbe35344f557671d8529770f73a3987c389ab0 100644
--- a/src/caosdb/authentication.cpp
+++ b/src/caosdb/authentication.cpp
@@ -19,13 +19,15 @@
  *
  */
 #include "caosdb/authentication.h"
-#include "grpcpp/security/credentials.h"    // for MetadataCredentialsPlugin
-#include <grpcpp/impl/codegen/status.h>     // for Status, Status::OK
-#include <grpcpp/impl/codegen/string_ref.h> // for string_ref
-#include <map>                              // for multimap
-#include <memory>                           // for allocator, shared_ptr
-#include <string>                           // for basic_string, operator+
-#include <utility>                          // for pair, move, make_pair
+#include <grpcpp/impl/codegen/interceptor.h>           // for Status
+#include <grpcpp/impl/codegen/security/auth_context.h> // for AuthContext
+#include <grpcpp/impl/codegen/status.h>                // for Status, Status::OK
+#include <grpcpp/impl/codegen/string_ref.h>            // for string_ref
+#include <grpcpp/security/credentials.h>               // for MetadataCredentialsPlugin
+#include <map>                                         // for multimap
+#include <memory>                                      // for allocator, shared_ptr
+#include <string>                                      // for basic_string, operator+
+#include <utility>                                     // for pair, move, make_pair
 
 namespace caosdb::authentication {
 using caosdb::utility::base64_encode;
diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp
index edce302e00bcb5645d734e2ff577be23d0a8bd67..3d78ac70600f2dcbb62199a40c6ec5d5a0299823 100644
--- a/src/caosdb/configuration.cpp
+++ b/src/caosdb/configuration.cpp
@@ -19,15 +19,6 @@
  *
  */
 #include "caosdb/configuration.h"
-#include "boost/iterator/iterator_facade.hpp"          // for iterator_facad...
-#include "boost/json/impl/object.hpp"                  // for object::at
-#include "boost/json/string.hpp"                       // for string
-#include "boost/json/string_view.hpp"                  // for string_view
-#include "boost/log/core/record.hpp"                   // for record
-#include "boost/log/detail/attachable_sstream_buf.hpp" // for basic_ostring...
-#include "boost/log/sources/record_ostream.hpp"        // for basic_record_o...
-#include "boost/preprocessor/seq/limits/enum_256.hpp"  // for BOOST_PP_SEQ_E...
-#include "boost/preprocessor/seq/limits/size_256.hpp"  // for BOOST_PP_SEQ_S...
 #include "caosdb/authentication.h"                     // for Authenticator
 #include "caosdb/connection.h"                         // for ConnectionManager
 #include "caosdb/constants.h"                          // for LIBCAOSDB_CONF...
@@ -35,6 +26,20 @@
 #include "caosdb/log_level.h"                          // for CAOSDB_DEFAULT...
 #include "caosdb/status_code.h"                        // for StatusCode
 #include "caosdb/utility.h"                            // for get_home_direc...
+#include <boost/filesystem/operations.hpp>             // for exists
+#include <boost/filesystem/path.hpp>                   // for path, path::i...
+#include <boost/iterator/iterator_facade.hpp>          // for iterator_facad...
+#include <boost/json/impl/object.hpp>                  // for object::at
+#include <boost/json/object.hpp>                       // for object, objec...
+#include <boost/json/string.hpp>                       // for string
+#include <boost/json/string_view.hpp>                  // for string_view
+#include <boost/json/value.hpp>                        // for value, key_va...
+#include <boost/json/value_ref.hpp>                    // for object
+#include <boost/log/core/record.hpp>                   // for record
+#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
+#include <boost/log/sources/record_ostream.hpp>        // for basic_record_o...
+#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_E...
+#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_S...
 #include <cassert>                                     // for assert
 #include <cstdlib>                                     // for getenv
 #include <cstring>                                     // for strcmp
diff --git a/src/caosdb/connection.cpp b/src/caosdb/connection.cpp
index d6782f8ffa42238888998bdff65dc666fbf55c18..8420d8ffe6459f3431ead22ab660ab6fcd6a50f3 100644
--- a/src/caosdb/connection.cpp
+++ b/src/caosdb/connection.cpp
@@ -25,12 +25,14 @@
 #include "caosdb/info.h"                          // for VersionInfo
 #include "caosdb/info/v1alpha1/main.grpc.pb.h"    // for GeneralInfoService
 #include "caosdb/info/v1alpha1/main.pb.h"         // for GetVersionInfoRequest
+#include "caosdb/protobuf_helper.h"               // for get_arena
 #include "caosdb/transaction.h"                   // for Transaction
 #include "caosdb/transaction_status.h"            // for TransactionStatus
-#include "grpcpp/impl/codegen/status_code_enum.h" // for StatusCode, UNAUTH...
+#include <google/protobuf/arena.h>                // for Arena
 #include <grpcpp/create_channel.h>                // for CreateChannel
 #include <grpcpp/impl/codegen/client_context.h>   // for ClientContext
 #include <grpcpp/impl/codegen/status.h>           // for Status
+#include <grpcpp/impl/codegen/status_code_enum.h> // for StatusCode, UNAUTH...
 #include <string>                                 // for string, operator+
 
 namespace caosdb::connection {
@@ -44,6 +46,8 @@ using caosdb::info::v1alpha1::GetVersionInfoRequest;
 using caosdb::info::v1alpha1::GetVersionInfoResponse;
 using caosdb::transaction::Transaction;
 using caosdb::transaction::TransactionStatus;
+using caosdb::utility::get_arena;
+using google::protobuf::Arena;
 
 Connection::Connection(const ConnectionConfiguration &configuration) {
   const std::string target =
@@ -57,11 +61,11 @@ Connection::Connection(const ConnectionConfiguration &configuration) {
 
 auto Connection::RetrieveVersionInfoNoExceptions() const noexcept -> TransactionStatus {
 
-  const GetVersionInfoRequest request;
-  GetVersionInfoResponse response;
+  const auto *request = Arena::CreateMessage<GetVersionInfoRequest>(get_arena());
+  auto *response = Arena::CreateMessage<GetVersionInfoResponse>(get_arena());
   grpc::ClientContext context;
   const grpc::Status grpc_status =
-    this->general_info_service->GetVersionInfo(&context, request, &response);
+    this->general_info_service->GetVersionInfo(&context, *request, response);
 
   auto status = TransactionStatus::SUCCESS();
   if (!grpc_status.ok()) {
@@ -78,7 +82,7 @@ auto Connection::RetrieveVersionInfoNoExceptions() const noexcept -> Transaction
                                             error_message);
     }
   } else {
-    this->version_info = std::make_unique<VersionInfo>(response.release_version_info());
+    this->version_info = std::make_unique<VersionInfo>(response->release_version_info());
   }
 
   return status;
diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp
index bb73431e4af00ed1db48b8f87fa883db6f4f9b31..a3872e4cb2be380adca644b7c7a109c0fec2b3c2 100644
--- a/src/caosdb/entity.cpp
+++ b/src/caosdb/entity.cpp
@@ -38,8 +38,6 @@ using ProtoFileDescriptor = caosdb::entity::v1alpha1::FileDescriptor;
 using caosdb::utility::get_arena;
 using google::protobuf::Arena;
 
-Messages::~Messages() = default;
-
 // Parent /////////////////////////////////////////////////////////////////////
 
 auto Parent::SetName(const std::string &name) -> void { this->wrapped->set_name(name); }
diff --git a/src/caosdb/file_transmission/download_request_handler.cpp b/src/caosdb/file_transmission/download_request_handler.cpp
index cbe79e93eb89261d1d85484cf39f4ad5deecba18..755c8a438f0634ee62761a257173918e53280b50 100644
--- a/src/caosdb/file_transmission/download_request_handler.cpp
+++ b/src/caosdb/file_transmission/download_request_handler.cpp
@@ -128,14 +128,22 @@ void DownloadRequestHandler::handleNewCallState() {
   CAOSDB_LOG_TRACE(logger_name) << "Enter DownloadRequestHandler::handleNewCallState. local_path = "
                                 << file_descriptor_.local_path
                                 << ", download_id = " << file_descriptor_.file_transmission_id;
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 1";
   fileWriter_ = std::make_unique<FileWriter>(file_descriptor_.local_path);
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 2";
 
-  request_->mutable_file_transmission_id()->CopyFrom(*(file_descriptor_.file_transmission_id));
+  auto *tid = request_->mutable_file_transmission_id();
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 3";
+  tid->CopyFrom(*(file_descriptor_.file_transmission_id));
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 4";
 
   rpc_ = stub_->PrepareAsyncFileDownload(&ctx_, *request_, cq_);
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 5";
 
   transaction_status = TransactionStatus::EXECUTING();
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 6";
   state_ = CallState::SendingRequest;
+  CAOSDB_LOG_TRACE(logger_name) << "HERE 7";
   rpc_->StartCall(tag_);
   CAOSDB_LOG_TRACE(logger_name) << "Leave DownloadRequestHandler::handleNewCallState";
 }
diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp
index 4070786b2bb4073da5800f4a57b9c0dfcff5d6ac..906bd7989d3b7b80ea4159bab1ae577c022abfe3 100644
--- a/src/caosdb/logging.cpp
+++ b/src/caosdb/logging.cpp
@@ -19,35 +19,43 @@
  *
  */
 #include "caosdb/logging.h"
-#include "boost/core/swap.hpp" // for swap
-#include "boost/iterator/iterator_facade.hpp"
-#include "boost/log/attributes/clock.hpp"
-#include "boost/log/core/core.hpp" // for core
-#include "boost/log/core/record.hpp"
-#include "boost/log/sources/record_ostream.hpp"
-#include "boost/log/utility/setup/from_settings.hpp"
-#include "boost/log/utility/setup/settings.hpp"
-#include "boost/move/utility_core.hpp" // for move
-#include "boost/multi_index/detail/bidir_node_iterator.hpp"
-#include "boost/operators.hpp"
-#include "boost/preprocessor/seq/limits/enum_256.hpp"
-#include "boost/preprocessor/seq/limits/size_256.hpp"
-#include "boost/property_tree/detail/exception_implementation.hpp"
-#include "boost/smart_ptr/shared_ptr.hpp"
-#include "boost/tuple/detail/tuple_basic.hpp" // for get
 #include "caosdb/log_level.h"
+#include <boost/core/swap.hpp> // for swap
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/log/attributes/clock.hpp>
+#include <boost/log/core/core.hpp> // for core
+#include <boost/log/core/record.hpp>
+#include <boost/log/sources/record_ostream.hpp>
+#include <boost/log/sources/severity_channel_logger.hpp>
+#include <boost/log/utility/setup/from_settings.hpp>
+#include <boost/log/utility/setup/settings.hpp>
+#include <boost/move/utility_core.hpp> // for move
+#include <boost/multi_index/detail/bidir_node_iterator.hpp>
+#include <boost/operators.hpp>
+#include <boost/preprocessor/seq/limits/enum_256.hpp>
+#include <boost/preprocessor/seq/limits/size_256.hpp>
+#include <boost/property_tree/detail/exception_implementation.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/tuple/detail/tuple_basic.hpp> // for get
+#include <iostream>
 #include <memory>
 #include <sstream>
 #include <string>
 #include <utility> // for move
 #include <vector>
 
+void __attribute__((constructor)) startup() {
+  std::cout << "LOADING CAOSDB 1" << std::endl;
+  boost::log::core::get()->set_logging_enabled(false);
+  std::cout << "LOADING CAOSDB 2" << std::endl;
+}
+void __attribute__((destructor)) shutdown() {
+  std::cout << "UNLOADING CAOSDB 1" << std::endl;
+  caosdb::logging::_logger::destroy();
+}
+
 namespace caosdb::logging {
 
-BOOST_LOG_GLOBAL_LOGGER_INIT(logger, boost_logger_class) {
-  boost_logger_class lg;
-  return lg;
-}
 LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {}
 
 auto LoggingConfiguration::AddSink(const std::shared_ptr<SinkConfiguration> &sink) -> void {
@@ -114,9 +122,12 @@ SyslogSinkConfiguration::SyslogSinkConfiguration(const std::string &name, int le
 // Called if no custom logging settings are specified.
 auto initialize_logging_defaults() -> int {
   // first: turn everything off
-  boost::log::settings off_settings;
-  off_settings["Core.DisableLogging"] = true;
-  boost::log::init_from_settings(off_settings);
+  auto core = boost::log::core::get();
+  if (core->get_logging_enabled()) {
+    core->flush();
+    core->remove_all_sinks();
+    core->set_logging_enabled(false);
+  }
 
   // now set everything up
   const static std::vector<std::shared_ptr<SinkConfiguration>> default_sinks = {
@@ -131,8 +142,7 @@ auto initialize_logging_defaults() -> int {
   }
 
   boost::log::init_from_settings(default_settings);
-  auto core = boost::log::core::get();
-  core->add_global_attribute("TimeStamp", boost::log::attributes::local_clock());
+  // core->add_global_attribute("TimeStamp", boost::log::attributes::local_clock());
 
   CAOSDB_LOG_DEBUG(logger_name) << "Initialized default settings.";
 
@@ -142,20 +152,22 @@ auto initialize_logging_defaults() -> int {
 // Called if custom logging settings are specified.
 auto initialize_logging(const LoggingConfiguration &configuration) -> void {
   // first: turn everything off
-  boost::log::settings off_settings;
-  off_settings["Core.DisableLogging"] = true;
-  boost::log::init_from_settings(off_settings);
-
-  // now set everything up
-  boost::log::settings new_settings;
+  auto core = boost::log::core::get();
+  if (core->get_logging_enabled()) {
+    core->flush();
+    core->remove_all_sinks();
+    core->set_logging_enabled(false);
+  }
 
   if (configuration.GetLevel() == CAOSDB_LOG_LEVEL_OFF) {
-    new_settings["Core.DisableLogging"] = true;
+    // it is off
     return;
-  } else {
-    new_settings["Core.DisableLogging"] = false;
   }
 
+  // now set everything up
+  boost::log::settings new_settings;
+  new_settings["Core.DisableLogging"] = false;
+
   for (const auto &sink : configuration.GetSinks()) {
     sink->Configure(new_settings);
   }
@@ -166,27 +178,27 @@ auto initialize_logging(const LoggingConfiguration &configuration) -> void {
 }
 
 void caosdb_log_fatal(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_FATAL) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_FATAL) << msg;
 }
 
 void caosdb_log_error(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_ERROR) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_ERROR) << msg;
 }
 
 void caosdb_log_warn(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_WARN) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_WARN) << msg;
 }
 
 void caosdb_log_info(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_INFO) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_INFO) << msg;
 }
 
 void caosdb_log_debug(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_DEBUG) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_DEBUG) << msg;
 }
 
 void caosdb_log_trace(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_TRACE) << msg;
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::get_logger(), channel, CAOSDB_LOG_LEVEL_TRACE) << msg;
 }
 
 } // namespace caosdb::logging
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index 002d20d792b49bfb88b160cb39e7d8a8e6a5bd01..d315bf890fdaf5d2382f4fe2b3d2e57ba3a57bc2 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -290,7 +290,7 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT
 
       switch (retrieve_response->retrieve_response_case()) {
       case RetrieveResponseCase::kEntityResponse: {
-        auto *retrieve_entity_response = retrieve_response->release_entity_response();
+        auto *retrieve_entity_response = retrieve_response->mutable_entity_response();
         result = std::make_unique<Entity>(retrieve_entity_response);
       } break;
       case RetrieveResponseCase::kSelectResult: {
@@ -321,17 +321,17 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT
     }
 
     case TransactionResponseCase::kInsertResponse: {
-      auto *inserted_id_response = sub_response.mutable_insert_response()->release_id_response();
+      auto *inserted_id_response = sub_response.mutable_insert_response()->mutable_id_response();
       result = std::make_unique<Entity>(inserted_id_response);
       break;
     }
     case TransactionResponseCase::kDeleteResponse: {
-      auto *deleted_id_response = sub_response.mutable_delete_response()->release_id_response();
+      auto *deleted_id_response = sub_response.mutable_delete_response()->mutable_id_response();
       result = std::make_unique<Entity>(deleted_id_response);
       break;
     }
     case TransactionResponseCase::kUpdateResponse: {
-      auto *updated_id_response = sub_response.mutable_update_response()->release_id_response();
+      auto *updated_id_response = sub_response.mutable_update_response()->mutable_id_response();
       result = std::make_unique<Entity>(updated_id_response);
       break;
     }
diff --git a/test/test_entity.cpp b/test/test_entity.cpp
index de0206f8b547884b7ae438b3bd4873230b9128d8..85f466f74e77f0806089ae71bed7b70f353fa1c8 100644
--- a/test/test_entity.cpp
+++ b/test/test_entity.cpp
@@ -44,7 +44,11 @@ namespace caosdb::entity {
 using caosdb::entity::v1alpha1::IdResponse;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
 using ProtoParent = caosdb::entity::v1alpha1::Parent;
+using ProtoProperty = caosdb::entity::v1alpha1::Property;
+using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType;
+using caosdb::entity::v1alpha1::EntityResponse;
 using caosdb::utility::get_arena;
+using ProtoEntityRole = caosdb::entity::v1alpha1::EntityRole;
 
 TEST(test_entity, test_parent_setters) {
   auto parent = Parent();
@@ -138,6 +142,129 @@ TEST(test_entity, test_append_property) {
   EXPECT_EQ(prop.GetDataType(), same_prop.GetDataType());
 }
 
+TEST(test_entity, test_copy_constructor) {
+  Arena arena;
+  auto *parent = Arena::CreateMessage<ProtoParent>(&arena);
+  parent->set_description("the parent desc");
+  parent->set_id("the parent id");
+  parent->set_name("the parent name");
+  auto *property = Arena::CreateMessage<ProtoProperty>(&arena);
+  property->set_id("the-prop-id");
+  property->set_description("the prop-desc");
+  property->set_name("the-prop-name");
+  property->mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5);
+  property->mutable_data_type()->mutable_list_data_type()->set_atomic_data_type(
+    ProtoAtomicDataType::ATOMIC_DATA_TYPE_DOUBLE);
+  auto *entity_response = Arena::CreateMessage<EntityResponse>(&arena);
+  entity_response->mutable_entity()->set_id("the-id");
+  entity_response->mutable_entity()->set_name("the-name");
+  entity_response->mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD);
+  entity_response->mutable_entity()->set_description("the description");
+  entity_response->mutable_entity()->set_unit("the-unit");
+  entity_response->mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value(
+    "the-value");
+  entity_response->mutable_entity()->mutable_version()->set_id("version-id");
+  entity_response->mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name(
+    "refname");
+  entity_response->mutable_entity()->mutable_file_descriptor();
+  entity_response->mutable_entity()->mutable_properties()->Add()->CopyFrom(*property);
+  entity_response->mutable_entity()->mutable_parents()->Add()->CopyFrom(*parent);
+
+  Entity this_entity(entity_response);
+  Entity copy_entity(this_entity);
+
+  EXPECT_EQ(this_entity, copy_entity);
+  EXPECT_EQ(this_entity.GetVersionId(), copy_entity.GetVersionId());
+  EXPECT_EQ(this_entity.GetValue(), copy_entity.GetValue());
+  EXPECT_EQ(this_entity.GetDataType(), copy_entity.GetDataType());
+  EXPECT_EQ(this_entity.GetId(), copy_entity.GetId());
+  EXPECT_EQ(this_entity.GetName(), copy_entity.GetName());
+  EXPECT_EQ(this_entity.GetDescription(), copy_entity.GetDescription());
+  EXPECT_EQ(this_entity.ToString(), copy_entity.ToString());
+  EXPECT_EQ(this_entity.GetErrors().ToString(), copy_entity.GetErrors().ToString());
+  EXPECT_EQ(this_entity.GetWarnings().ToString(), copy_entity.GetWarnings().ToString());
+  EXPECT_EQ(this_entity.GetInfos().ToString(), copy_entity.GetInfos().ToString());
+  EXPECT_EQ(this_entity.GetProperties(), copy_entity.GetProperties());
+
+  // change only description
+  this_entity.SetDescription("new description");
+  EXPECT_NE(this_entity, copy_entity);
+  EXPECT_EQ(this_entity.GetVersionId(), copy_entity.GetVersionId());
+  EXPECT_EQ(this_entity.GetValue(), copy_entity.GetValue());
+  EXPECT_EQ(this_entity.GetDataType(), copy_entity.GetDataType());
+  EXPECT_EQ(this_entity.GetId(), copy_entity.GetId());
+  EXPECT_EQ(this_entity.GetName(), copy_entity.GetName());
+  EXPECT_NE(this_entity.GetDescription(), copy_entity.GetDescription());
+  EXPECT_NE(this_entity.ToString(), copy_entity.ToString());
+}
+
+TEST(test_entity, test_move_constructor) {
+  Arena arena;
+  auto *parent = Arena::CreateMessage<ProtoParent>(&arena);
+  parent->set_description("the parent desc");
+  parent->set_id("the parent id");
+  parent->set_name("the parent name");
+  auto *property = Arena::CreateMessage<ProtoProperty>(&arena);
+  property->set_id("the-prop-id");
+  property->set_description("the prop-desc");
+  property->set_name("the-prop-name");
+  property->mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5);
+  property->mutable_data_type()->mutable_list_data_type()->set_atomic_data_type(
+    ProtoAtomicDataType::ATOMIC_DATA_TYPE_DOUBLE);
+  auto *entity_response = Arena::CreateMessage<EntityResponse>(&arena);
+  entity_response->mutable_errors()->Add()->set_code(25);
+  entity_response->mutable_errors()->Mutable(0)->set_description("asdf");
+  entity_response->mutable_warnings()->Add()->set_code(23);
+  entity_response->mutable_warnings()->Mutable(0)->set_description("asdgsafdg");
+  entity_response->mutable_infos()->Add()->set_code(235);
+  entity_response->mutable_infos()->Mutable(0)->set_description("asdfsad");
+  entity_response->mutable_entity()->set_id("the-id");
+  entity_response->mutable_entity()->set_name("the-name");
+  entity_response->mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD);
+  entity_response->mutable_entity()->set_description("the description");
+  entity_response->mutable_entity()->set_unit("the-unit");
+  entity_response->mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value(
+    "the-value");
+  entity_response->mutable_entity()->mutable_version()->set_id("version-id");
+  entity_response->mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name(
+    "refname");
+  entity_response->mutable_entity()->mutable_file_descriptor();
+  entity_response->mutable_entity()->mutable_properties()->Add()->CopyFrom(*property);
+  entity_response->mutable_entity()->mutable_parents()->Add()->CopyFrom(*parent);
+
+  Entity this_entity(entity_response);
+  std::string original_string = this_entity.ToString();
+  Entity copy_entity(this_entity);
+  EXPECT_EQ(this_entity, copy_entity);
+
+  Entity move_entity(std::move(this_entity));
+  EXPECT_NE(this_entity, copy_entity); // NOLINT
+
+  EXPECT_EQ(move_entity, copy_entity);
+  EXPECT_EQ(move_entity.GetVersionId(), copy_entity.GetVersionId());
+  EXPECT_EQ(move_entity.GetValue(), copy_entity.GetValue());
+  EXPECT_EQ(move_entity.GetDataType(), copy_entity.GetDataType());
+  EXPECT_EQ(move_entity.GetId(), copy_entity.GetId());
+  EXPECT_EQ(move_entity.GetName(), copy_entity.GetName());
+  EXPECT_EQ(move_entity.GetDescription(), copy_entity.GetDescription());
+  EXPECT_EQ(move_entity.ToString(), copy_entity.ToString());
+  EXPECT_EQ(move_entity.GetErrors().ToString(), copy_entity.GetErrors().ToString());
+  EXPECT_EQ(move_entity.GetWarnings().ToString(), copy_entity.GetWarnings().ToString());
+  EXPECT_EQ(move_entity.GetInfos().ToString(), copy_entity.GetInfos().ToString());
+  EXPECT_EQ(move_entity.GetProperties(), copy_entity.GetProperties());
+
+  // change only description
+  move_entity.SetDescription("new description");
+  EXPECT_NE(move_entity, copy_entity);
+  EXPECT_EQ(move_entity.GetVersionId(), copy_entity.GetVersionId());
+  EXPECT_EQ(move_entity.GetValue(), copy_entity.GetValue());
+  EXPECT_EQ(move_entity.GetDataType(), copy_entity.GetDataType());
+  EXPECT_EQ(move_entity.GetId(), copy_entity.GetId());
+  EXPECT_EQ(move_entity.GetName(), copy_entity.GetName());
+  EXPECT_NE(move_entity.GetDescription(), copy_entity.GetDescription());
+  EXPECT_NE(move_entity.ToString(), copy_entity.ToString());
+}
+
 TEST(test_entity, test_property_copy_constructor) {
   Property prop;
   prop.SetName("prop_name");
@@ -191,15 +318,18 @@ TEST(test_entity, test_property_move_assignment) {
   prop.SetValue("prop_value");
   prop.SetUnit("prop_unit");
   prop.SetDataType("prop_dtype");
+  const auto prop_string = prop.ToString();
 
   // we compare the moved one with this one
   const Property copy_prop(prop);
 
-  Property other_prop = std::move(prop);
-  // EXPECT_NE(prop, copy_prop);  NOLINT
-  // EXPECT_NE(prop, other_prop);  NOLINT
-  // EXPECT_EQ(prop.ToString(), "{}"); NOLINT
+  Property other_prop = std::move(prop);   // NOLINT
+  EXPECT_NE(prop, copy_prop);              // NOLINT
+  EXPECT_NE(prop, other_prop);             // NOLINT
+  EXPECT_NE(prop.ToString(), prop_string); // NOLINT
 
+  EXPECT_EQ(copy_prop.ToString(), prop_string);
+  EXPECT_EQ(other_prop.ToString(), prop_string);
   EXPECT_EQ(copy_prop, other_prop);
   EXPECT_EQ(copy_prop.GetName(), other_prop.GetName());
   EXPECT_EQ(copy_prop.GetId(), other_prop.GetId());
@@ -542,10 +672,11 @@ TEST(test_entity, test_description) {
 
   entity.SetDescription("desc entity");
   property.SetDescription("desc property");
-  // Parent has not setter
-  ProtoParent protoParent;
-  protoParent.set_description("desc parent");
-  parent = Parent(&protoParent);
+  // Parent has no setter
+  Arena arena;
+  auto *protoParent = Arena::CreateMessage<ProtoParent>(&arena);
+  protoParent->set_description("desc parent");
+  parent = Parent(protoParent);
 
   EXPECT_EQ(entity.GetDescription(), "desc entity");
   EXPECT_EQ(property.GetDescription(), "desc property");
@@ -565,6 +696,35 @@ TEST(test_entity, test_add_file) {
   EXPECT_EQ(entity.SetLocalPath(TEST_DATA_DIR + "/test.json"), StatusCode::SUCCESS);
 }
 
+TEST(test_entity, test_move_assign) {
+  Entity entity1;
+  entity1.SetRole(Role::RECORD_TYPE);
+  entity1.SetName("E1");
+  entity1.SetValue("some-string-1");
+  entity1.SetDataType("some-other-string-1");
+
+  Entity entity2;
+  entity1.SetRole(Role::RECORD);
+  entity1.SetName("E2");
+  entity1.SetValue("some-string-2");
+  entity1.SetDataType("some-other-string-2");
+
+  const Entity copy1(entity1); // NOLINT
+  const Entity copy2(entity2); // NOLINT
+
+  EXPECT_EQ(copy1, entity1);
+  EXPECT_EQ(copy2, entity2);
+
+  // Swap
+  Entity tmp;
+  tmp = std::move(entity1);
+  entity1 = std::move(entity2);
+  entity2 = std::move(tmp);
+
+  EXPECT_EQ(copy2, entity1);
+  EXPECT_EQ(copy1, entity2);
+}
+
 TEST(test_entity, test_entity_to_string) {
   Entity entity;
   EXPECT_EQ(entity.ToString(), "{}\n");
@@ -623,13 +783,14 @@ TEST(test_entity, test_parent_to_string) {
 }
 
 TEST(test_entity, test_messages_to_string) {
-  IdResponse idResponse;
-  idResponse.set_id("entity_id");
-  auto *error = idResponse.add_errors();
+  Arena arena;
+  auto *idResponse = Arena::CreateMessage<IdResponse>(&arena);
+  idResponse->set_id("entity_id");
+  auto *error = idResponse->add_errors();
   error->set_code(MessageCode::ENTITY_DOES_NOT_EXIST);
   error->set_description("error_desc");
 
-  Entity entity(&idResponse);
+  Entity entity(idResponse);
 
   // Messages are not printed, currently.
   EXPECT_EQ(entity.ToString(), "{\n \"id\": \"entity_id\",\n \"version\": {}\n}\n");
@@ -638,13 +799,14 @@ TEST(test_entity, test_messages_to_string) {
 }
 
 TEST(test_entity, test_message_to_string) {
-  IdResponse idResponse;
-  idResponse.set_id("entity_id");
-  auto *error = idResponse.add_errors();
+  Arena arena;
+  auto *idResponse = Arena::CreateMessage<IdResponse>(&arena);
+  idResponse->set_id("entity_id");
+  auto *error = idResponse->add_errors();
   error->set_code(MessageCode::ENTITY_DOES_NOT_EXIST);
   error->set_description("error_desc");
 
-  Entity entity(&idResponse);
+  Entity entity(idResponse);
 
   // Messages are not printed, currently.
   EXPECT_EQ(entity.ToString(), "{\n \"id\": \"entity_id\",\n \"version\": {}\n}\n");
diff --git a/test/test_misc.cpp b/test/test_misc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dccaaa817a8a926772502723a231f379d04764dc
--- /dev/null
+++ b/test/test_misc.cpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+ * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+ *
+ * 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/>.
+ *
+ */
+#include <gtest/gtest-message.h>   // for Message
+#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl
+#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST
+#include <iostream>                // for cout, <<
+#include <string>                  // for string
+#include <utility>                 // for move
+
+namespace caosdb {
+
+class TestClass {
+public:
+  ~TestClass() = default;
+  TestClass(TestClass &&other) = default;
+  TestClass(const TestClass &other);
+  TestClass();
+  explicit TestClass(std::string member);
+
+  auto operator=(const TestClass &other) -> TestClass &;
+  auto operator=(TestClass &&other) -> TestClass & = default;
+
+  [[nodiscard]] auto ToString() const -> std::string;
+  std::string member;
+};
+
+TestClass::TestClass() { std::cout << "Constructor TestClass(): " << ToString() << "\n"; }
+
+TestClass::TestClass(std::string member) : member(std::move(member)) {
+  std::cout << "Constructor TestClass(const std:string &): " << ToString() << "\n";
+}
+
+TestClass::TestClass(const TestClass &other) : member(other.member) {
+  std::cout << "Copy Constructor TestClass(const TestClass &): " << ToString() << "\n";
+}
+
+auto TestClass::operator=(const TestClass &other) -> TestClass & {
+  std::cout << "Copy assignment (" << ToString() << "->";
+  if (this != &other) {
+    this->member = other.member;
+  }
+  std::cout << ToString() << ")\n";
+  return *this;
+}
+
+auto TestClass::ToString() const -> std::string { return "TestClass(" + member + ")"; }
+
+TEST(test_misc, test_move) {
+  TestClass test_class1;
+  std::cout << "test_class1: " << test_class1.ToString() << "\n";
+
+  TestClass test_class2 = test_class1;
+  std::cout << "test_class2: " << test_class2.ToString() << "\n";
+
+  const TestClass test_class3("member3");
+  std::cout << "test_class3: " << test_class3.ToString() << "\n";
+
+  TestClass test_class4 = test_class3;
+  std::cout << "test_class4: " << test_class4.ToString() << "\n";
+}
+
+} // namespace caosdb
diff --git a/test/test_protobuf.cpp b/test/test_protobuf.cpp
index 6f9bda0740487db475f1e34757e4a612c59061f9..8dde7fe056048f9f91d0c9a7a9d209af3263ae32 100644
--- a/test/test_protobuf.cpp
+++ b/test/test_protobuf.cpp
@@ -22,86 +22,91 @@
 #include "caosdb/data_type.h"               // for DataType, ReferenceDataType
 #include "caosdb/entity.h"                  // for Entity
 #include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message
+#include <google/protobuf/arena.h>          // for Arena
 #include <gtest/gtest-message.h>            // for Message
 #include <gtest/gtest-test-part.h>          // for SuiteApiResolver, TestPa...
 #include <gtest/gtest_pred_impl.h>          // for Test, TestInfo, TEST
 #include <memory>                           // for allocator
 
 namespace caosdb {
+using google::protobuf::Arena;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
 using caosdb::entity::Entity;
 using caosdb::entity::v1alpha1::Message;
 
 TEST(test_protobuf, test_swap_trivial) {
-  Message message_source;
-  message_source.set_code(1234);
-  message_source.set_description("desc");
+  Arena arena;
+  auto *message_source = Arena::CreateMessage<Message>(&arena);
+  message_source->set_code(1234);
+  message_source->set_description("desc");
 
-  Message message_destination;
+  auto *message_destination = Arena::CreateMessage<Message>(&arena);
 
-  EXPECT_EQ(message_source.code(), 1234);
-  EXPECT_EQ(message_source.description(), "desc");
-  EXPECT_EQ(message_destination.code(), 0);
-  EXPECT_EQ(message_destination.description(), "");
+  EXPECT_EQ(message_source->code(), 1234);
+  EXPECT_EQ(message_source->description(), "desc");
+  EXPECT_EQ(message_destination->code(), 0);
+  EXPECT_EQ(message_destination->description(), "");
 
-  message_source.Swap(&message_destination);
+  message_source->Swap(message_destination);
 
-  EXPECT_EQ(message_source.code(), 0);
-  EXPECT_EQ(message_source.description(), "");
-  EXPECT_EQ(message_destination.code(), 1234);
-  EXPECT_EQ(message_destination.description(), "desc");
+  EXPECT_EQ(message_source->code(), 0);
+  EXPECT_EQ(message_source->description(), "");
+  EXPECT_EQ(message_destination->code(), 1234);
+  EXPECT_EQ(message_destination->description(), "desc");
 }
 
 TEST(test_protobuf, test_swap_nested) {
-  ProtoEntity entity_source;
-  entity_source.set_id("entity_id");
-  auto *version_source = entity_source.mutable_version();
+  Arena arena;
+  auto *entity_source = Arena::CreateMessage<ProtoEntity>(&arena);
+  entity_source->set_id("entity_id");
+  auto *version_source = entity_source->mutable_version();
   version_source->set_id("version_id");
 
-  ProtoEntity entity_destination;
-  auto *version_destination = entity_destination.mutable_version();
+  auto *entity_destination = Arena::CreateMessage<ProtoEntity>(&arena);
+  auto *version_destination = entity_destination->mutable_version();
 
-  EXPECT_EQ(entity_source.id(), "entity_id");
-  EXPECT_EQ(entity_source.version().id(), "version_id");
+  EXPECT_EQ(entity_source->id(), "entity_id");
+  EXPECT_EQ(entity_source->version().id(), "version_id");
   EXPECT_EQ(version_source->id(), "version_id");
-  EXPECT_EQ(entity_destination.id(), "");
-  EXPECT_EQ(entity_destination.version().id(), "");
+  EXPECT_EQ(entity_destination->id(), "");
+  EXPECT_EQ(entity_destination->version().id(), "");
   EXPECT_EQ(version_destination->id(), "");
 
-  entity_source.Swap(&entity_destination);
+  entity_source->Swap(entity_destination);
 
-  EXPECT_EQ(entity_source.id(), "");
-  EXPECT_EQ(entity_source.version().id(), "");
-  EXPECT_EQ(entity_destination.id(), "entity_id");
-  EXPECT_EQ(entity_destination.version().id(), "version_id");
+  EXPECT_EQ(entity_source->id(), "");
+  EXPECT_EQ(entity_source->version().id(), "");
+  EXPECT_EQ(entity_destination->id(), "entity_id");
+  EXPECT_EQ(entity_destination->version().id(), "version_id");
 
   // has not been swapped!
   EXPECT_EQ(version_source->id(), "version_id");
   EXPECT_EQ(version_destination->id(), "");
 
   // Member pointers to nested messages have been swapped
-  EXPECT_EQ(entity_source.mutable_version(), version_destination);
-  EXPECT_EQ(entity_destination.mutable_version(), version_source);
+  EXPECT_EQ(entity_source->mutable_version(), version_destination);
+  EXPECT_EQ(entity_destination->mutable_version(), version_source);
 }
 
 TEST(test_protobuf, test_copy_nested) {
-  ProtoEntity entity_source;
-  auto *data_type_source = entity_source.mutable_data_type();
+  Arena arena;
+  auto *entity_source = Arena::CreateMessage<ProtoEntity>(&arena);
+  auto *data_type_source = entity_source->mutable_data_type();
   data_type_source->mutable_reference_data_type()->set_name("src_per");
 
-  ProtoEntity entity_destination;
-  auto *data_type_destination = entity_destination.mutable_data_type();
+  auto *entity_destination = Arena::CreateMessage<ProtoEntity>(&arena);
+  auto *data_type_destination = entity_destination->mutable_data_type();
   data_type_destination->mutable_reference_data_type()->set_name("dest_per");
 
-  EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per");
-  EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "dest_per");
+  EXPECT_EQ(entity_source->data_type().reference_data_type().name(), "src_per");
+  EXPECT_EQ(entity_destination->data_type().reference_data_type().name(), "dest_per");
 
-  entity_destination.CopyFrom(entity_source);
+  entity_destination->CopyFrom(*entity_source);
 
-  EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per");
-  EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "src_per");
+  EXPECT_EQ(entity_source->data_type().reference_data_type().name(), "src_per");
+  EXPECT_EQ(entity_destination->data_type().reference_data_type().name(), "src_per");
 
-  Entity entity(&entity_destination);
+  Entity entity(entity_destination);
   EXPECT_EQ(entity.GetDataType().GetAsReference().GetName(), "src_per");
 
   const Entity &copy_entity(entity);
diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp
index 7c93ac5d9b081ac4cb2314f34272f54cba0f61c9..34c33d6560bfa68c5510055b23f7daedb29e734a 100644
--- a/test/test_transaction.cpp
+++ b/test/test_transaction.cpp
@@ -27,6 +27,7 @@
 #include "caosdb/transaction_handler.h" // for MultiTransactionResponse
 #include "caosdb/transaction_status.h"  // for ConnectionError
 #include "caosdb_test_utility.h"        // for EXPECT_THROW_MESSAGE
+#include <google/protobuf/arena.h>      // for Arena
 #include <gtest/gtest-message.h>        // for Message
 #include <gtest/gtest-test-part.h>      // for SuiteApiResolver, TestPa...
 #include <gtest/gtest_pred_impl.h>      // for Test, TestInfo, TEST
@@ -40,10 +41,9 @@ namespace caosdb::transaction {
 using caosdb::configuration::InsecureConnectionConfiguration;
 using caosdb::connection::Connection;
 using caosdb::entity::Entity;
-using caosdb::exceptions::ConnectionError;
-using ProtoEntity = caosdb::entity::v1alpha1::Entity;
 using caosdb::entity::Role;
 using caosdb::entity::v1alpha1::RetrieveResponse;
+using caosdb::exceptions::ConnectionError;
 
 TEST(test_transaction, create_transaction) {
   const auto *host = "localhost";
@@ -113,9 +113,10 @@ TEST(test_transaction, test_multi_result_set_empty) {
 
 TEST(test_transaction, test_multi_result_iterator) {
   std::vector<std::unique_ptr<Entity>> one_elem;
-  RetrieveResponse response;
-  response.mutable_entity_response()->mutable_entity()->set_id("100");
-  one_elem.push_back(std::make_unique<Entity>(response.release_entity_response()));
+  Arena arena;
+  auto *response = Arena::CreateMessage<RetrieveResponse>(&arena);
+  response->mutable_entity_response()->mutable_entity()->set_id("100");
+  one_elem.push_back(std::make_unique<Entity>(response->mutable_entity_response()));
 
   MultiResultSet rs(std::move(one_elem));
   EXPECT_EQ(rs.size(), 1);
@@ -127,9 +128,10 @@ TEST(test_transaction, test_multi_result_iterator) {
 
 TEST(test_transaction, test_multi_result_set_one) {
   std::vector<std::unique_ptr<Entity>> one_elem;
-  RetrieveResponse response;
-  response.mutable_entity_response()->mutable_entity()->set_id("100");
-  one_elem.push_back(std::make_unique<Entity>(response.release_entity_response()));
+  Arena arena;
+  auto *response = Arena::CreateMessage<RetrieveResponse>(&arena);
+  response->mutable_entity_response()->mutable_entity()->set_id("100");
+  one_elem.push_back(std::make_unique<Entity>(response->mutable_entity_response()));
 
   MultiResultSet rs(std::move(one_elem));
   EXPECT_EQ(rs.size(), 1);
@@ -139,27 +141,28 @@ TEST(test_transaction, test_multi_result_set_one) {
 TEST(test_transaction, test_multi_result_set_three) {
   std::vector<std::unique_ptr<Entity>> three_elem;
 
-  MultiTransactionResponse response;
-  response.add_responses()
+  Arena arena;
+  auto *response = Arena::CreateMessage<MultiTransactionResponse>(&arena);
+  response->add_responses()
     ->mutable_retrieve_response()
     ->mutable_entity_response()
     ->mutable_entity()
     ->set_id("100");
   auto *entity_with_error =
-    response.add_responses()->mutable_retrieve_response()->mutable_entity_response();
+    response->add_responses()->mutable_retrieve_response()->mutable_entity_response();
   entity_with_error->mutable_entity()->set_id("101");
   entity_with_error->add_errors()->set_code(1);
-  response.add_responses()
+  response->add_responses()
     ->mutable_retrieve_response()
     ->mutable_entity_response()
     ->mutable_entity()
     ->set_id("102");
 
-  auto *responses = response.mutable_responses();
+  auto *responses = response->mutable_responses();
   std::vector<std::unique_ptr<Entity>> entities;
   for (auto sub_response : *responses) {
     three_elem.push_back(std::make_unique<Entity>(
-      sub_response.mutable_retrieve_response()->release_entity_response()));
+      sub_response.mutable_retrieve_response()->mutable_entity_response()));
   }
 
   MultiResultSet rs(std::move(three_elem));