diff --git a/include/caosdb/value.h b/include/caosdb/value.h
index 20bbead6afee5c1e9f2e2a9a86c2705600bf4411..7bf0f7d3f9a7e0c55f7ccf48fd0af536baec5e1e 100644
--- a/include/caosdb/value.h
+++ b/include/caosdb/value.h
@@ -162,6 +162,7 @@ public:
    * The return value is undefined if IsVector is false.
    */
   [[nodiscard]] virtual auto GetAsVector() const noexcept -> const std::vector<ScalarValue> & = 0;
+  [[nodiscard]] virtual auto ToString() const noexcept -> const std::string = 0;
   friend class Value;
 
 protected:
@@ -250,6 +251,11 @@ public:
     static const std::vector<ScalarValue> empty_collection;
     return empty_collection;
   }
+  inline auto ToString() const noexcept -> const std::string {
+    CAOSDB_DEBUG_MESSAGE_STRING(*wrapped, out)
+    return out;
+  }
+
   friend class Value;
 
 protected:
@@ -286,7 +292,9 @@ public:
   explicit inline Value(const ScalarValue &value) : Value() {
     this->wrapped->mutable_scalar_value()->CopyFrom(*value.wrapped);
   }
-  explicit inline Value(const AbstractValue &value) : Value(value.GetProtoValue()) {}
+  explicit inline Value(const AbstractValue &value) : Value() {
+    this->wrapped->CopyFrom(*value.GetProtoValue());
+  }
   explicit inline Value(ProtoValue *wrapped) : ProtoMessageWrapper<ProtoValue>(wrapped) {}
   explicit inline Value(const std::string &value) : ProtoMessageWrapper<ProtoValue>() {
     this->wrapped->mutable_scalar_value()->set_string_value(value);
diff --git a/test/test_value.cpp b/test/test_value.cpp
index 15d70a391265530798b756f2bd0ba4b50a932031..5e6773b01ab749cc70cc294cb09eb253d0b6b4ae 100644
--- a/test/test_value.cpp
+++ b/test/test_value.cpp
@@ -147,4 +147,37 @@ TEST(test_value, test_scalar_value_to_value) {
   EXPECT_EQ(scalar_value.GetAsInt64(), value.GetAsInt64());
 }
 
+TEST(test_value, test_abstract_value) {
+  std::vector<double> vals;
+  for (double num : {0.0, 5.6, 27.5}) {
+    vals.push_back(num);
+  }
+  Value value(vals);
+  EXPECT_EQ("", value.ToString());
+  EXPECT_TRUE(value.IsVector());
+
+  AbstractValue *abstract_value = &value;
+  EXPECT_EQ("", abstract_value->ToString());
+  EXPECT_TRUE(abstract_value->IsVector());
+
+  Value value2(*abstract_value);
+  EXPECT_EQ("", value2.ToString());
+  EXPECT_TRUE(value2.IsVector());
+
+  ScalarValue scalar_value = value.GetAsVector().at(2);
+  EXPECT_TRUE(scalar_value.IsDouble());
+  EXPECT_EQ("", scalar_value.ToString());
+  EXPECT_EQ(scalar_value.GetAsDouble(), 27.5);
+
+  AbstractValue *abstract_scalar_value = &scalar_value;
+  EXPECT_EQ("", abstract_scalar_value->ToString());
+  EXPECT_TRUE(abstract_scalar_value->IsDouble());
+  EXPECT_EQ(abstract_scalar_value->GetAsDouble(), 27.5);
+
+  Value scalar_value2(*abstract_scalar_value);
+  EXPECT_TRUE(scalar_value2.IsDouble());
+  EXPECT_EQ("", scalar_value2.ToString());
+  EXPECT_EQ(scalar_value2.GetAsDouble(), 27.5);
+}
+
 } // namespace caosdb::entity