diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index 831200c0ff7fdafbd265bb4778b62f51003b6836..08a7be6b0f6f2b42752ff78f2a004e7196e9e757 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -454,7 +454,9 @@ class Property {
 public:
   explicit inline Property(ProtoProperty *other)
     : value(Value(other->mutable_value())), data_type(DataType(other->mutable_data_type())),
-      wrapped(other){};
+      wrapped(other) {
+    FixValue();
+  };
   Property();
 
   /**
@@ -551,6 +553,12 @@ public:
   friend class RepeatedPtrFieldWrapper<Property, ProtoProperty>;
 
 private:
+  /**
+   * Workaround until non-string values are supported by the server.
+   *
+   * Only has an effect if there is a DataType.
+   */
+  auto FixValue() -> void;
   static auto CreateProtoProperty() -> ProtoProperty *;
   Value value;
   DataType data_type;
@@ -602,6 +610,7 @@ public:
     errors.wrapped = CreateMessagesField();
     warnings.wrapped = CreateMessagesField();
     infos.wrapped = CreateMessagesField();
+    FixValue();
   };
   explicit Entity(IdResponse *id_response);
   explicit Entity(ProtoEntity *other)
@@ -614,11 +623,13 @@ public:
     errors.wrapped = CreateMessagesField();
     warnings.wrapped = CreateMessagesField();
     infos.wrapped = CreateMessagesField();
+    FixValue();
   };
   explicit inline Entity(EntityResponse *response) : Entity(response->release_entity()) {
     errors.wrapped->Swap(response->mutable_errors());
     warnings.wrapped->Swap(response->mutable_warnings());
     infos.wrapped->Swap(response->mutable_infos());
+    FixValue();
   };
 
   [[nodiscard]] inline auto GetId() const noexcept -> const std::string & { return wrapped->id(); };
@@ -744,6 +755,13 @@ private:
   auto SetId(const std::string &id) -> void;
   auto SetVersionId(const std::string &id) -> void;
 
+  /**
+   * Workaround until non-string values are supported by the server.
+   *
+   * Only has an effect if there is a DataType.
+   */
+  auto FixValue() -> void;
+
 private:
   FileDescriptor file_descriptor;
   ProtoEntity *wrapped;
diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp
index 16ea5dbfc99b173efdac9bdbbfe0d87a2e289fee..21ad8af8da006b14fb13860278758aec15376fe4 100644
--- a/src/caosdb/entity.cpp
+++ b/src/caosdb/entity.cpp
@@ -20,10 +20,12 @@
  *
  */
 #include "caosdb/entity.h"
-#include "caosdb/data_type.h"                       // for DataType
-#include "caosdb/entity/v1alpha1/main.pb.h"         // for Messages
-#include "caosdb/protobuf_helper.h"                 // for get_arena
-#include "caosdb/value.h"                           // for Value
+#include "caosdb/data_type.h"               // for DataType
+#include "caosdb/entity/v1alpha1/main.pb.h" // for Messages
+#include "caosdb/exceptions.h"
+#include "caosdb/protobuf_helper.h"         // for get_arena
+#include "caosdb/value.h"                   // for Value
+#include <boost/algorithm/string.hpp>
 #include <google/protobuf/arena.h>                  // for Arena
 #include <google/protobuf/generated_message_util.h> // for Arena::Create...
 #include <new>                                      // for operator new
@@ -42,6 +44,12 @@ using google::protobuf::Arena;
 
 Messages::~Messages() = default;
 
+// Forward declarations ///////////////////////////////////////////////////////
+
+template <typename E> auto FixValueImpl(E *ent) -> void;
+
+// Parent /////////////////////////////////////////////////////////////////////
+
 Parent::Parent() : wrapped(Parent::CreateProtoParent()) {
   // TODO(fspreck) Re-enable once we have decided how to attach
   // messages to parents.
@@ -66,7 +74,7 @@ auto Parent::SetId(const std::string &id) -> void { this->wrapped->set_id(id); }
   return this->wrapped->description();
 }
 
-Property::Property() : Property(Property::CreateProtoProperty()) {}
+Property::Property() : Property(Property::CreateProtoProperty()) { FixValue(); }
 
 auto Property::CreateProtoProperty() -> ProtoProperty * {
   return Arena::CreateMessage<ProtoProperty>(get_arena());
@@ -152,6 +160,9 @@ auto Property::SetDataType(const std::string &new_data_type, bool list_type) ->
   return SetDataType(DataType(new_data_type, list_type));
 }
 
+auto Property::FixValue() -> void { FixValueImpl(this); }
+
+// Entity /////////////////////////////////////////////////////////////////////
 [[nodiscard]] auto Entity::GetParents() const -> const Parents & { return parents; }
 
 auto Entity::AppendParent(const Parent &parent) -> void { this->parents.Append(parent); }
@@ -174,9 +185,10 @@ Entity::Entity(IdResponse *id_response) : Entity() {
   this->errors.wrapped->Swap(id_response->mutable_errors());
   this->warnings.wrapped->Swap(id_response->mutable_warnings());
   this->infos.wrapped->Swap(id_response->mutable_infos());
+  FixValue();
 }
 
-Entity::Entity() : Entity(Entity::CreateProtoEntity()) {}
+Entity::Entity() : Entity(Entity::CreateProtoEntity()) { FixValue(); }
 
 auto Entity::CreateMessagesField() -> RepeatedPtrField<ProtoMessage> * {
   return Arena::CreateMessage<RepeatedPtrField<ProtoMessage>>(get_arena());
@@ -256,4 +268,98 @@ auto Entity::SetFilePath(const std::string &path) -> void {
   this->wrapped->mutable_file_descriptor()->set_path(path);
 }
 
+auto Entity::FixValue() -> void { FixValueImpl(this); }
+
+// Utility functions //////////////////////////////////////////////////////////
+
+template <typename E> auto FixValueImpl(E *ent) -> void {
+  const auto &dtype = ent->GetDataType();
+  const auto &value = ent->GetValue();
+  auto new_value = Value();
+  if (value.IsNull() || !value.IsString()) { // Don't treat NULL and non-string values.
+    return;
+  }
+  if (value.IsList()) { // Also don't treat empty or non-string lists.
+    const auto &list = value.AsList();
+    if (list.empty() || !list[0].IsString()) {
+      return;
+    }
+  }
+  auto atype = AtomicDataType::UNSPECIFIED;
+  if (dtype.IsList()) { // List Datatype
+    if (!value.IsList()) {
+      throw caosdb::exceptions::Exception(StatusCode::OTHER_CLIENT_ERROR,
+                                          "DataType is list, but Value is scalar.");
+    }
+    auto &list_type = dtype.AsList();
+    atype = list_type.GetAtomicDataType();
+    if (!list_type.IsListOfAtomic() // References, strings etc. need no treatment.
+        || atype == AtomicDataType::UNSPECIFIED || atype == AtomicDataType::TEXT ||
+        atype == AtomicDataType::DATETIME) {
+      return;
+    }
+    if (atype == AtomicDataType::DOUBLE) {
+      std::vector<double> data;
+      for (auto &d : value.AsList()) {
+        data.push_back(std::stod(d.AsString()));
+      }
+      new_value = Value(data);
+    } else if (atype == AtomicDataType::INTEGER) {
+      std::vector<int64_t> data;
+      for (auto &d : value.AsList()) {
+        data.push_back(std::stol(d.AsString()));
+      }
+      new_value = Value(data);
+    } else if (atype == AtomicDataType::BOOLEAN) {
+      std::vector<bool> data;
+      for (auto &d : value.AsList()) {
+        const auto &bool_value = d.AsString();
+        if (boost::to_upper_copy(bool_value) == "TRUE") {
+          data.push_back(true);
+        } else if (boost::to_upper_copy(bool_value) == "FALSE") {
+          data.push_back(false);
+        } else {
+          throw caosdb::exceptions::Exception(StatusCode::OTHER_CLIENT_ERROR,
+                                              "Boolean value is neither true nor false.");
+        }
+      }
+      new_value = Value(data);
+    } else {
+      std::cout << "Unhandled datatype: " << ent->ToString() << std::endl;
+      throw std::logic_error("Unhandled datatype");
+    }
+  } else { // Scalar Datatype
+    if (value.IsList()) {
+      throw caosdb::exceptions::Exception(StatusCode::OTHER_CLIENT_ERROR,
+                                          "Value is list, but DataType is scalar.");
+    }
+    atype = dtype.AsAtomic();
+    if (!dtype.IsAtomic() // References, strings etc. need no treatment.
+        || atype == AtomicDataType::UNSPECIFIED || atype == AtomicDataType::TEXT ||
+        atype == AtomicDataType::DATETIME) {
+      return;
+    }
+    if (atype == AtomicDataType::DOUBLE) {
+      new_value = Value(std::stod(value.AsString()));
+    } else if (atype == AtomicDataType::INTEGER) {
+      new_value = Value(std::stol(value.AsString()));
+    } else if (atype == AtomicDataType::BOOLEAN) {
+      const auto &bool_value = value.AsString();
+      if (boost::to_upper_copy(bool_value) == "TRUE") {
+        new_value = Value(true);
+      } else if (boost::to_upper_copy(bool_value) == "FALSE") {
+        new_value = Value(false);
+      } else {
+        throw caosdb::exceptions::Exception(StatusCode::OTHER_CLIENT_ERROR,
+                                            "Boolean value is neither true nor false.");
+      }
+    } else {
+      std::cout << "Unhandled datatype: " << ent->ToString() << std::endl;
+      throw std::logic_error("Unhandled datatype");
+    }
+  }
+
+  ent->SetValue(new_value);
+}
+
 } // namespace caosdb::entity